Merge "The PV aac software decoder screws up if playing a mono-AACplus stream unless we output stereo data. Now we always output stereo data as the legacy OMX nodes did."
diff --git a/api/current.xml b/api/current.xml
index 031506b..8a9a77a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -71453,6 +71453,28 @@
visibility="public"
>
</method>
+<method name="getExposureCompensation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getExposureCompensationStep"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getFlashMode"
return="java.lang.String"
abstract="false"
@@ -71543,6 +71565,28 @@
visibility="public"
>
</method>
+<method name="getMaxExposureCompensation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMinExposureCompensation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getPictureFormat"
return="int"
abstract="false"
@@ -71843,6 +71887,19 @@
<parameter name="value" type="java.lang.String">
</parameter>
</method>
+<method name="setExposureCompensation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+</method>
<method name="setFlashMode"
return="void"
abstract="false"
@@ -89978,6 +90035,356 @@
</package>
<package name="android.net.http"
>
+<class name="AndroidHttpClient"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="org.apache.http.client.HttpClient">
+</implements>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="disableCurlLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="enableCurlLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+<parameter name="level" type="int">
+</parameter>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="org.apache.http.HttpResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler<? extends T>">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.client.methods.HttpUriRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler<? extends T>">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler<? extends T>">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="execute"
+ return="T"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="org.apache.http.HttpHost">
+</parameter>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+<parameter name="responseHandler" type="org.apache.http.client.ResponseHandler<? extends T>">
+</parameter>
+<parameter name="context" type="org.apache.http.protocol.HttpContext">
+</parameter>
+<exception name="ClientProtocolException" type="org.apache.http.client.ClientProtocolException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getCompressedEntity"
+ return="org.apache.http.entity.AbstractHttpEntity"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<parameter name="resolver" type="android.content.ContentResolver">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getConnectionManager"
+ return="org.apache.http.conn.ClientConnectionManager"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMinGzipSize"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="resolver" type="android.content.ContentResolver">
+</parameter>
+</method>
+<method name="getParams"
+ return="org.apache.http.params.HttpParams"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUngzippedContent"
+ return="java.io.InputStream"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="entity" type="org.apache.http.HttpEntity">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="modifyRequestToAcceptGzipResponse"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="request" type="org.apache.http.HttpRequest">
+</parameter>
+</method>
+<method name="newInstance"
+ return="android.net.http.AndroidHttpClient"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="userAgent" type="java.lang.String">
+</parameter>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</method>
+<method name="newInstance"
+ return="android.net.http.AndroidHttpClient"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="userAgent" type="java.lang.String">
+</parameter>
+</method>
+<field name="DEFAULT_SYNC_MIN_GZIP_BYTES"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="HttpDateTime"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="HttpDateTime"
+ type="android.net.http.HttpDateTime"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="parse"
+ return="java.lang.Long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timeString" type="java.lang.String">
+</parameter>
+<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
+</exception>
+</method>
+</class>
<class name="SslCertificate"
extends="java.lang.Object"
abstract="false"
@@ -137783,6 +138190,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_CALLING_PACKAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""calling_package""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="EXTRA_LANGUAGE"
type="java.lang.String"
transient="false"
@@ -163521,6 +163939,134 @@
>
</field>
</class>
+<class name="Patterns"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="concatGroups"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="matcher" type="java.util.regex.Matcher">
+</parameter>
+</method>
+<method name="digitsAndPlusOnly"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="matcher" type="java.util.regex.Matcher">
+</parameter>
+</method>
+<field name="DOMAIN_NAME"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EMAIL_ADDRESS"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GOOD_IRI_CHAR"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""a-zA-Z0-9\u00a0-\ud7ff\uf900-\ufdcf\ufdf0-\uffef""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IP_ADDRESS"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOP_LEVEL_DOMAIN"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOP_LEVEL_DOMAIN_STR"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""((aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(biz|b[abdefghijmnorstvwyz])|(cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(edu|e[cegrstu])|f[ijkmor]|(gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(info|int|i[delmnoqrst])|(jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(name|net|n[acefgilopruz])|(org|om)|(pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)|y[etu]|z[amw])""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)|y[etu]|z[amw]))""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEB_URL"
+ type="java.util.regex.Pattern"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="PrintStreamPrinter"
extends="java.lang.Object"
abstract="false"
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 66f3676..8e4adb1 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -68,7 +68,7 @@
/* other handy constants */
#define PROTECTED_DIR_PREFIX "/data/app-private/"
-#define SDCARD_DIR_PREFIX "/mnt/asec/"
+#define SDCARD_DIR_PREFIX getenv("ASEC_MOUNTPOINT")
#define DALVIK_CACHE_PREFIX "/data/dalvik-cache/"
#define DALVIK_CACHE_POSTFIX "/classes.dex"
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index 0c7ca83..0a48fe7 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -17,6 +17,7 @@
package com.android.common;
import android.content.SharedPreferences;
+import android.net.http.HttpDateTime;
import android.text.format.Time;
import java.util.Map;
diff --git a/common/java/com/android/common/speech/Recognition.java b/common/java/com/android/common/speech/Recognition.java
index 6f164a9..a79a19b 100644
--- a/common/java/com/android/common/speech/Recognition.java
+++ b/common/java/com/android/common/speech/Recognition.java
@@ -19,18 +19,42 @@
/**
* Utilities for voice recognition implementations.
*
- * @see android.app.RecognitionService
+ * @see android.speech.RecognitionService
+ * @see android.speech.RecognizerIntent
*/
public class Recognition {
-
+
/**
- * The extra key used in an intent to the speech recognizer for voice search. Not
- * generally to be used by developers. The system search dialog uses this, for example,
- * to set a calling package for identification by a voice search API. If this extra
- * is set by anyone but the system process, it should be overridden by the voice search
- * implementation.
+ * The key to the extra in the Bundle returned by
+ * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS
+ * which is an ArrayList of CharSequences which are hints that can be shown to
+ * the user for voice actions currently supported by voice search for the user's current
+ * language preference for voice search (i.e., the one defined in the extra
+ * android.speech.RecognizerIntent#EXTRA_LANGUAGE_PREFERENCE).
+ *
+ * If this is paired with EXTRA_HINT_CONTEXT, should return a set of hints that are
+ * appropriate for the provided context.
+ *
+ * The CharSequences are SpannedStrings and will contain segments wrapped in
+ * <annotation action="true"></annotation>. This is to indicate the section of the text
+ * which represents the voice action, to be highlighted in the UI if so desired.
*/
- public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+ public static final String EXTRA_HINT_STRINGS = "android.speech.extra.HINT_STRINGS";
+
+ /**
+ * The key to an extra to be included in the request intent for
+ * android.speech.RecognizerIntent#ACTION_GET_LANGUAGE_DETAILS.
+ * Should be an int of one of the values defined below. If an
+ * unknown int value is provided, it should be ignored.
+ */
+ public static final String EXTRA_HINT_CONTEXT = "android.speech.extra.HINT_CONTEXT";
+
+ /**
+ * A set of values for EXTRA_HINT_CONTEXT.
+ */
+ public static final int HINT_CONTEXT_UNKNOWN = 0;
+ public static final int HINT_CONTEXT_VOICE_SEARCH_HELP = 1;
+ public static final int HINT_CONTEXT_CAR_HOME = 2;
private Recognition() { } // don't instantiate
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b38aeda..8695598 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -678,17 +678,19 @@
private Thread mUiThread;
private final Handler mHandler = new Handler();
+ // Used for debug only
+ /*
public Activity() {
++sInstanceCount;
}
-
@Override
protected void finalize() throws Throwable {
super.finalize();
--sInstanceCount;
}
-
+ */
+
public static long getInstanceCount() {
return sInstanceCount;
}
diff --git a/core/java/android/app/AliasActivity.java b/core/java/android/app/AliasActivity.java
index 7527a5b..3756529 100644
--- a/core/java/android/app/AliasActivity.java
+++ b/core/java/android/app/AliasActivity.java
@@ -26,7 +26,8 @@
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Xml;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
import java.io.IOException;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 50dcdf9..8335bf3 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -17,7 +17,7 @@
package android.app;
import com.android.internal.policy.PolicyManager;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import com.google.android.collect.Maps;
import org.xmlpull.v1.XmlPullParserException;
@@ -209,11 +209,14 @@
private static final String[] EMPTY_FILE_LIST = {};
+ // For debug only
+ /*
@Override
protected void finalize() throws Throwable {
super.finalize();
--sInstanceCount;
}
+ */
public static long getInstanceCount() {
return sInstanceCount;
@@ -1446,7 +1449,8 @@
}
ContextImpl() {
- ++sInstanceCount;
+ // For debug only
+ //++sInstanceCount;
mOuterContext = this;
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 6a02a58..af68689 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -16,8 +16,6 @@
package android.app;
-import com.android.common.Patterns;
-import com.android.common.speech.Recognition;
import static android.app.SuggestionsAdapter.getColumnString;
@@ -48,6 +46,7 @@
import android.util.AndroidRuntimeException;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Patterns;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.KeyEvent;
@@ -313,7 +312,6 @@
mLaunchComponent = null;
mAppSearchData = null;
mSearchable = null;
- mActivityContext = null;
mUserQuery = null;
}
@@ -411,7 +409,7 @@
updateSearchAppIcon();
updateSearchBadge();
updateQueryHint();
- updateVoiceButton();
+ updateVoiceButton(TextUtils.isEmpty(mUserQuery));
// In order to properly configure the input method (if one is being used), we
// need to let it know if we'll be providing suggestions. Although it would be
@@ -560,10 +558,13 @@
/**
* Update the visibility of the voice button. There are actually two voice search modes,
* either of which will activate the button.
+ * @param empty whether the search query text field is empty. If it is, then the other
+ * criteria apply to make the voice button visible. Otherwise the voice button will not
+ * be visible - i.e., if the user has typed a query, remove the voice button.
*/
- private void updateVoiceButton() {
+ private void updateVoiceButton(boolean empty) {
int visibility = View.GONE;
- if (mSearchable.getVoiceSearchEnabled()) {
+ if (mSearchable.getVoiceSearchEnabled() && empty) {
Intent testIntent = null;
if (mSearchable.getVoiceSearchLaunchWebSearch()) {
testIntent = mVoiceWebSearchIntent;
@@ -666,6 +667,7 @@
// The user changed the query, remember it.
mUserQuery = s == null ? "" : s.toString();
}
+ updateVoiceButton(TextUtils.isEmpty(s));
}
public void afterTextChanged(Editable s) {
@@ -746,9 +748,6 @@
return;
}
SearchableInfo searchable = mSearchable;
- // First stop the existing search before starting voice search, or else we'll end
- // up showing the search dialog again once we return to the app.
- cancel();
try {
if (searchable.getVoiceSearchLaunchWebSearch()) {
getContext().startActivity(mVoiceWebSearchIntent);
@@ -762,6 +761,7 @@
// voice search before showing the button. But just in case...
Log.w(LOG_TAG, "Could not find voice search activity");
}
+ dismiss();
}
};
@@ -819,7 +819,7 @@
voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
- voiceIntent.putExtra(Recognition.EXTRA_CALLING_PACKAGE,
+ voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
searchActivity == null ? null : searchActivity.toShortString());
// Add the values that configure forwarding the results
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 607605d..fb3f646 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -34,7 +34,8 @@
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
import java.io.IOException;
import java.io.Serializable;
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 023c024..452fd8a 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -34,7 +34,8 @@
import android.util.Config;
import android.util.Log;
import android.util.Printer;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
/**
* Structured description of Intent values to be matched. An IntentFilter can
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index fcb910d..5aad3af 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -18,7 +18,7 @@
import com.android.internal.os.AtomicFile;
import com.android.internal.util.ArrayUtils;
-import com.android.common.FastXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 98aacaa..b07bafcf 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -30,12 +30,14 @@
import android.os.Build;
import android.os.Bundle;
import android.os.PatternMatcher;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Config;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
import java.io.File;
import java.io.IOException;
@@ -710,9 +712,10 @@
com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
}
sa.recycle();
+
pkg.installLocation = sa.getInteger(
com.android.internal.R.styleable.AndroidManifest_installLocation,
- PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ PackageInfo.INSTALL_LOCATION_AUTO);
// Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index a885820..b74c073 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -43,7 +43,7 @@
import java.io.FileInputStream;
import com.android.internal.os.AtomicFile;
-import com.android.common.FastXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
import com.google.android.collect.Maps;
import com.google.android.collect.Lists;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a5e39d4..0608cc0 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -17,7 +17,7 @@
package android.content.res;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index 2411177..5e90b91 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -24,7 +24,8 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
/**
* Conveniences for retrieving data out of a compiled string resource.
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 8f0003b..a7fb31d 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -5,7 +5,8 @@
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
import java.util.Arrays;
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index 3c2c30a..ad1bfb2 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -17,7 +17,8 @@
package android.content.res;
import android.util.TypedValue;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 6dba94d..da5fa49 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -724,6 +724,9 @@
private static final String KEY_HORIZONTAL_VIEW_ANGLE = "horizontal-view-angle";
private static final String KEY_VERTICAL_VIEW_ANGLE = "vertical-view-angle";
private static final String KEY_EXPOSURE_COMPENSATION = "exposure-compensation";
+ private static final String KEY_MAX_EXPOSURE_COMPENSATION = "max-exposure-compensation";
+ private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
+ private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -1543,38 +1546,63 @@
}
/**
- * Gets the current exposure compensation setting.
+ * Gets the current exposure compensation index.
*
- * @return the current exposure compensation value multiplied by 100.
- * null if exposure compensation is not supported. Ex: -100
- * means -1 EV. 130 means +1.3 EV.
- * @hide
+ * @return current exposure compensation index. The range is {@link
+ * #getMinExposureCompensation} to {@link
+ * #getMaxExposureCompensation}. 0 means exposure is not
+ * adjusted.
*/
public int getExposureCompensation() {
- return getInt(KEY_EXPOSURE_COMPENSATION);
+ return getInt(KEY_EXPOSURE_COMPENSATION, 0);
}
/**
- * Sets the exposure compensation.
+ * Sets the exposure compensation index.
*
- * @param value exposure compensation multiplied by 100. Ex: -100 means
- * -1 EV. 130 means +1.3 EV.
- * @hide
+ * @param value exposure compensation index. The valid value range is
+ * from {@link #getMinExposureCompensation} (inclusive) to {@link
+ * #getMaxExposureCompensation} (inclusive). 0 means exposure is
+ * not adjusted. Application should call
+ * getMinExposureCompensation and getMaxExposureCompensation to
+ * know if exposure compensation is supported.
*/
public void setExposureCompensation(int value) {
set(KEY_EXPOSURE_COMPENSATION, value);
}
/**
- * Gets the supported exposure compensation.
+ * Gets the maximum exposure compensation index.
*
- * @return a List of Integer constants. null if exposure compensation is
- * not supported. The list is sorted from small to large. Ex:
- * -100, -66, -33, 0, 33, 66, 100.
- * @hide
+ * @return maximum exposure compensation index (>=0). If both this
+ * method and {@link #getMinExposureCompensation} return 0,
+ * exposure compensation is not supported.
*/
- public List<Integer> getSupportedExposureCompensation() {
- return splitInt(get(KEY_EXPOSURE_COMPENSATION + SUPPORTED_VALUES_SUFFIX));
+ public int getMaxExposureCompensation() {
+ return getInt(KEY_MAX_EXPOSURE_COMPENSATION, 0);
+ }
+
+ /**
+ * Gets the minimum exposure compensation index.
+ *
+ * @return minimum exposure compensation index (<=0). If both this
+ * method and {@link #getMaxExposureCompensation} return 0,
+ * exposure compensation is not supported.
+ */
+ public int getMinExposureCompensation() {
+ return getInt(KEY_MIN_EXPOSURE_COMPENSATION, 0);
+ }
+
+ /**
+ * Gets the exposure compensation step.
+ *
+ * @return exposure compensation step. Applications can get EV by
+ * multiplying the exposure compensation index and step. Ex: if
+ * exposure compensation index is -6 and step is 0.333333333, EV
+ * is -2.
+ */
+ public float getExposureCompensationStep() {
+ return getFloat(KEY_EXPOSURE_COMPENSATION_STEP, 0);
}
/**
@@ -1680,6 +1708,24 @@
return substrings;
}
+ // Returns the value of a float parameter.
+ private float getFloat(String key, float defaultValue) {
+ try {
+ return Float.parseFloat(mMap.get(key));
+ } catch (NumberFormatException ex) {
+ return defaultValue;
+ }
+ }
+
+ // Returns the value of a integer parameter.
+ private int getInt(String key, int defaultValue) {
+ try {
+ return Integer.parseInt(mMap.get(key));
+ } catch (NumberFormatException ex) {
+ return defaultValue;
+ }
+ }
+
// Splits a comma delimited string to an ArrayList of Size.
// Return null if the passing string is null or the size is 0.
private ArrayList<Size> splitSize(String str) {
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index f959fee..6941e57 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -16,11 +16,12 @@
package android.net;
+import com.android.internal.net.DomainNameValidator;
+
import android.os.SystemProperties;
import android.util.Config;
import android.util.Log;
-import com.android.common.DomainNameValidator;
import java.io.IOException;
import java.net.InetAddress;
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index fa13894..a572f60 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -16,7 +16,7 @@
package android.net;
-import static com.android.common.Patterns.GOOD_IRI_CHAR;
+import static android.util.Patterns.GOOD_IRI_CHAR;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/common/java/com/android/common/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java
similarity index 98%
rename from common/java/com/android/common/AndroidHttpClient.java
rename to core/java/android/net/http/AndroidHttpClient.java
index 4c65eb0..3517737 100644
--- a/common/java/com/android/common/AndroidHttpClient.java
+++ b/core/java/android/net/http/AndroidHttpClient.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.common;
+package android.net.http;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
@@ -36,7 +36,6 @@
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.RequestWrapper;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
@@ -55,7 +54,6 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.net.URI;
-import java.security.KeyManagementException;
import android.content.Context;
import android.content.ContentResolver;
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index e1327dd..c527fe4 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -16,7 +16,8 @@
package android.net.http;
-import com.android.common.DomainNameValidator;
+
+import com.android.internal.net.DomainNameValidator;
import org.apache.harmony.xnet.provider.jsse.SSLParameters;
diff --git a/common/java/com/android/common/HttpDateTime.java b/core/java/android/net/http/HttpDateTime.java
similarity index 98%
rename from common/java/com/android/common/HttpDateTime.java
rename to core/java/android/net/http/HttpDateTime.java
index f4052cc..c7a31ee 100644
--- a/common/java/com/android/common/HttpDateTime.java
+++ b/core/java/android/net/http/HttpDateTime.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.common;
+package android.net.http;
import android.text.format.Time;
@@ -22,8 +22,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-
-/** {@hide} */
+/**
+ * Helper for parsing an HTTP date.
+ */
public final class HttpDateTime {
/*
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index cb42d73..c9dab60 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -19,15 +19,15 @@
import android.accounts.Account;
import android.app.AlarmManager;
import android.app.PendingIntent;
+import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
-import android.content.Intent;
-import android.content.EntityIterator;
import android.content.CursorEntityIterator;
import android.content.Entity;
-import android.content.ContentProviderClient;
+import android.content.EntityIterator;
+import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
@@ -408,6 +408,12 @@
public static final String SELF_ATTENDEE_STATUS = "selfAttendeeStatus";
/**
+ * This column is available for use by sync adapters
+ * <P>Type: TEXT</P>
+ */
+ public static final String SYNC_ADAPTER_DATA = "syncAdapterData";
+
+ /**
* The comments feed uri.
* <P>Type: TEXT</P>
*/
@@ -644,6 +650,7 @@
mProvider = provider;
}
+ @Override
public Entity getEntityAndIncrementCursor(Cursor cursor) throws RemoteException {
// we expect the cursor is already at the row we need to read from
final long eventId = cursor.getLong(cursor.getColumnIndexOrThrow(Events._ID));
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1163106..0b90f91 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3201,28 +3201,33 @@
public static final String SNIPPET_MIMETYPE = "snippet_mimetype";
/**
- * The {@link CommonDataKinds.CommonColumns#DATA} field of the data row
- * that was matched by the filter.
+ * The {@link Data#DATA1} field of the data row that was matched by the filter.
*
* @hide
*/
- public static final String SNIPPET_DATA = "snippet_data";
+ public static final String SNIPPET_DATA1 = "snippet_data1";
/**
- * The {@link CommonDataKinds.CommonColumns#TYPE} field of the data row
- * that was matched by the filter.
+ * The {@link Data#DATA2} field of the data row that was matched by the filter.
*
* @hide
*/
- public static final String SNIPPET_TYPE = "snippet_type";
+ public static final String SNIPPET_DATA2 = "snippet_data2";
/**
- * The {@link CommonDataKinds.CommonColumns#LABEL} field of the data row
- * that was matched by the filter.
+ * The {@link Data#DATA3} field of the data row that was matched by the filter.
*
* @hide
*/
- public static final String SNIPPET_LABEL = "snippet_label";
+ public static final String SNIPPET_DATA3 = "snippet_data3";
+
+ /**
+ * The {@link Data#DATA4} field of the data row that was matched by the filter.
+ *
+ * @hide
+ */
+ public static final String SNIPPET_DATA4 = "snippet_data4";
+
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b75a8cc..081cf32 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1647,6 +1647,9 @@
TTY_MODE,
SOUND_EFFECTS_ENABLED,
HAPTIC_FEEDBACK_ENABLED,
+ POWER_SOUNDS_ENABLED,
+ DOCK_SOUNDS_ENABLED,
+ LOCKSCREEN_SOUNDS_ENABLED,
SHOW_WEB_SUGGESTIONS,
NOTIFICATION_LIGHT_PULSE
};
@@ -3095,6 +3098,7 @@
PARENTAL_CONTROL_REDIRECT_URL,
USB_MASS_STORAGE_ENABLED,
ACCESSIBILITY_ENABLED,
+ BACKUP_AUTO_RESTORE,
ENABLED_ACCESSIBILITY_SERVICES,
TTS_USE_DEFAULTS,
TTS_DEFAULT_RATE,
diff --git a/core/java/android/provider/SyncConstValue.java b/core/java/android/provider/SyncConstValue.java
index 30966eb..2fcf315 100644
--- a/core/java/android/provider/SyncConstValue.java
+++ b/core/java/android/provider/SyncConstValue.java
@@ -18,6 +18,7 @@
/**
* Columns for tables that are synced to a server.
+ * @deprecated
* @hide
*/
public interface SyncConstValue
@@ -69,7 +70,7 @@
* <P>Type: INTEGER (long)</P>
*/
public static final String _SYNC_DIRTY = "_sync_dirty";
-
+
/**
* Used to indicate that this account is not synced
*/
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index adeef54..d96596295 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -29,8 +29,8 @@
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
+import android.util.Patterns;
-import com.android.common.Patterns;
import java.util.HashSet;
import java.util.Set;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index aa20ac4..e7d9d5b 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -52,12 +52,17 @@
import com.android.internal.app.IBatteryStats;
import java.io.BufferedInputStream;
+import java.io.BufferedReader;
import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -65,7 +70,6 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Random;
public class BluetoothService extends IBluetooth.Stub {
private static final String TAG = "BluetoothService";
@@ -528,6 +532,7 @@
persistBluetoothOnSetting(true);
}
mIsDiscovering = false;
+ mBondState.readAutoPairingData();
mBondState.loadBondState();
mHandler.sendMessageDelayed(
mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
@@ -580,34 +585,17 @@
public class BondState {
private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
- private final ArrayList<String> mAutoPairingFailures = new ArrayList<String>();
- // List of all the vendor_id prefix of Bluetooth addresses for
- // which auto pairing is not attempted.
- // The following companies are included in the list below:
- // ALPS (lexus), Murata (Prius 2007, Nokia 616), TEMIC SDS (Porsche, Audi),
- // Parrot, Zhongshan General K-mate Electronics, Great Well
- // Electronics, Flaircomm Electronics, Jatty Electronics, Delphi,
- // Clarion, Novero, Denso (Lexus, Toyota), Johnson Controls (Acura),
- // Continental Automotive, Harman/Becker, Panasonic/Kyushu Ten,
- // BMW (Motorola PCS)
- private final ArrayList<String> mAutoPairingAddressBlacklist =
- new ArrayList<String>(Arrays.asList(
- "00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", "00:21:4F",
- "00:23:06", "00:24:33", "00:A0:79", "00:0E:6D", "00:13:E0", "00:21:E8",
- "00:60:57", "00:0E:9F", "00:12:1C", "00:18:91", "00:18:96", "00:13:04",
- "00:16:FD", "00:22:A0", "00:0B:4C", "00:60:6F", "00:23:3D", "00:C0:59",
- "00:0A:30", "00:1E:AE", "00:1C:D7", "00:80:F0", "00:12:8A"
- ));
- // List of names of Bluetooth devices for which auto pairing should be
- // disabled.
- private final ArrayList<String> mAutoPairingExactNameBlacklist =
- new ArrayList<String>(Arrays.asList(
- "Motorola IHF1000", "i.TechBlueBAND", "X5 Stereo v1.3"));
+ private static final String AUTO_PAIRING_BLACKLIST =
+ "/etc/bluetooth/auto_pairing.conf";
+ private static final String DYNAMIC_AUTO_PAIRING_BLACKLIST =
+ "/data/misc/bluetooth/dynamic_auto_pairing.conf";
+ private ArrayList<String> mAutoPairingAddressBlacklist;
+ private ArrayList<String> mAutoPairingExactNameBlacklist;
+ private ArrayList<String> mAutoPairingPartialNameBlacklist;
+ // Addresses added to blacklist dynamically based on usage.
+ private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
- private final ArrayList<String> mAutoPairingPartialNameBlacklist =
- new ArrayList<String>(Arrays.asList(
- "BMW", "Audi"));
// If this is an outgoing connection, store the address.
// There can be only 1 pending outgoing connection at a time,
@@ -682,18 +670,29 @@
}
public boolean isAutoPairingBlacklisted(String address) {
- for (String blacklistAddress : mAutoPairingAddressBlacklist) {
- if (address.startsWith(blacklistAddress)) return true;
+ if (mAutoPairingAddressBlacklist != null) {
+ for (String blacklistAddress : mAutoPairingAddressBlacklist) {
+ if (address.startsWith(blacklistAddress)) return true;
+ }
}
+ if (mAutoPairingDynamicAddressBlacklist != null) {
+ for (String blacklistAddress: mAutoPairingDynamicAddressBlacklist) {
+ if (address.equals(blacklistAddress)) return true;
+ }
+ }
String name = getRemoteName(address);
if (name != null) {
- for (String blacklistName : mAutoPairingExactNameBlacklist) {
- if (name.equals(blacklistName)) return true;
+ if (mAutoPairingExactNameBlacklist != null) {
+ for (String blacklistName : mAutoPairingExactNameBlacklist) {
+ if (name.equals(blacklistName)) return true;
+ }
}
- for (String blacklistName : mAutoPairingPartialNameBlacklist) {
- if (name.startsWith(blacklistName)) return true;
+ if (mAutoPairingPartialNameBlacklist != null) {
+ for (String blacklistName : mAutoPairingPartialNameBlacklist) {
+ if (name.startsWith(blacklistName)) return true;
+ }
}
}
return false;
@@ -718,9 +717,12 @@
}
public synchronized void addAutoPairingFailure(String address) {
- if (!mAutoPairingFailures.contains(address)) {
- mAutoPairingFailures.add(address);
+ if (mAutoPairingDynamicAddressBlacklist == null) {
+ mAutoPairingDynamicAddressBlacklist = new ArrayList<String>();
}
+
+ updateAutoPairingData(address);
+ mAutoPairingDynamicAddressBlacklist.add(address);
}
public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
@@ -732,7 +734,9 @@
}
public synchronized boolean hasAutoPairingFailed(String address) {
- return mAutoPairingFailures.contains(address);
+ if (mAutoPairingDynamicAddressBlacklist == null) return false;
+
+ return mAutoPairingDynamicAddressBlacklist.contains(address);
}
public synchronized int getAttempt(String address) {
@@ -754,6 +758,108 @@
mPinAttempt.put(address, new Integer(newAttempt));
}
+ private void copyAutoPairingData() {
+ File file = null;
+ FileInputStream in = null;
+ FileOutputStream out = null;
+ try {
+ file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+ if (file.exists()) return;
+
+ in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
+ out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
+ } catch (FileNotFoundException e) {
+ log("FileNotFoundException: in copyAutoPairingData");
+ } catch (IOException e) {
+ log("IOException: in copyAutoPairingData");
+ } finally {
+ try {
+ if (in != null) in.close();
+ if (out != null) out.close();
+ } catch (IOException e) {}
+ }
+ }
+
+ public void readAutoPairingData() {
+ if (mAutoPairingAddressBlacklist != null) return;
+ copyAutoPairingData();
+ FileInputStream fstream = null;
+ try {
+ fstream = new FileInputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader file = new BufferedReader(new InputStreamReader(in));
+ String line;
+ while((line = file.readLine()) != null) {
+ line = line.trim();
+ if (line.length() == 0 || line.startsWith("//")) continue;
+ String[] value = line.split("=");
+ if (value != null && value.length == 2) {
+ String[] val = value[1].split(",");
+ if (value[0].equalsIgnoreCase("AddressBlacklist")) {
+ mAutoPairingAddressBlacklist =
+ new ArrayList<String>(Arrays.asList(val));
+ } else if (value[0].equalsIgnoreCase("ExactNameBlacklist")) {
+ mAutoPairingExactNameBlacklist =
+ new ArrayList<String>(Arrays.asList(val));
+ } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
+ mAutoPairingPartialNameBlacklist =
+ new ArrayList<String>(Arrays.asList(val));
+ } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
+ mAutoPairingDynamicAddressBlacklist =
+ new ArrayList<String>(Arrays.asList(val));
+ } else {
+ Log.e(TAG, "Error parsing Auto pairing blacklist file");
+ }
+ }
+ }
+ } catch (FileNotFoundException e) {
+ log("FileNotFoundException: readAutoPairingData" + e.toString());
+ } catch (IOException e) {
+ log("IOException: readAutoPairingData" + e.toString());
+ } finally {
+ if (fstream != null) {
+ try {
+ fstream.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ // This function adds a bluetooth address to the auto pairing blacklis
+ // file. These addresses are added to DynamicAddressBlacklistSection
+ private void updateAutoPairingData(String address) {
+ BufferedWriter out = null;
+ try {
+ out = new BufferedWriter(new FileWriter(DYNAMIC_AUTO_PAIRING_BLACKLIST, true));
+ StringBuilder str = new StringBuilder();
+ if (mAutoPairingDynamicAddressBlacklist.size() == 0) {
+ str.append("DynamicAddressBlacklist=");
+ }
+ str.append(address);
+ str.append(",");
+ out.write(str.toString());
+ } catch (FileNotFoundException e) {
+ log("FileNotFoundException: updateAutoPairingData" + e.toString());
+ } catch (IOException e) {
+ log("IOException: updateAutoPairingData" + e.toString());
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ }
}
private static String toBondStateString(int bondState) {
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index 7c15cec..bf411e1 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -32,6 +32,15 @@
* Constants for supporting speech recognition through starting an {@link Intent}
*/
public class RecognizerIntent {
+ /**
+ * The extra key used in an intent to the speech recognizer for voice search. Not
+ * generally to be used by developers. The system search dialog uses this, for example,
+ * to set a calling package for identification by a voice search API. If this extra
+ * is set by anyone but the system process, it should be overridden by the voice search
+ * implementation.
+ */
+ public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+
private RecognizerIntent() {
// Not for instantiating.
}
diff --git a/core/java/android/test/InstrumentationTestCase.java b/core/java/android/test/InstrumentationTestCase.java
index 22d95d1..cd33d8a 100644
--- a/core/java/android/test/InstrumentationTestCase.java
+++ b/core/java/android/test/InstrumentationTestCase.java
@@ -16,8 +16,6 @@
package android.test;
-import junit.framework.TestCase;
-
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
@@ -26,9 +24,11 @@
import android.view.KeyEvent;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.lang.reflect.InvocationTargetException;
+
+import junit.framework.TestCase;
/**
* A test case that has access to {@link Instrumentation}.
@@ -86,7 +86,6 @@
* @param extras Optional extra stuff to pass to the activity.
* @return The activity, or null if non launched.
*/
- @SuppressWarnings("unchecked")
public final <T extends Activity> T launchActivity(
String pkg,
Class<T> activityCls,
@@ -338,6 +337,7 @@
*
* @throws Exception
*/
+ @Override
protected void tearDown() throws Exception {
Runtime.getRuntime().gc();
Runtime.getRuntime().runFinalization();
diff --git a/core/java/android/text/AndroidBidi.java b/core/java/android/text/AndroidBidi.java
new file mode 100644
index 0000000..e4f934e
--- /dev/null
+++ b/core/java/android/text/AndroidBidi.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/**
+ * Access the ICU bidi implementation.
+ * @hide
+ */
+/* package */ class AndroidBidi {
+
+ public static int bidi(int dir, char[] chs, byte[] chInfo, int n, boolean haveInfo) {
+ if (chs == null || chInfo == null) {
+ throw new NullPointerException();
+ }
+
+ if (n < 0 || chs.length < n || chInfo.length < n) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ switch(dir) {
+ case Layout.DIR_REQUEST_LTR: dir = 0; break;
+ case Layout.DIR_REQUEST_RTL: dir = 1; break;
+ case Layout.DIR_REQUEST_DEFAULT_LTR: dir = -2; break;
+ case Layout.DIR_REQUEST_DEFAULT_RTL: dir = -1; break;
+ default: dir = 0; break;
+ }
+
+ int result = runBidi(dir, chs, chInfo, n, haveInfo);
+ result = (result & 0x1) == 0 ? Layout.DIR_LEFT_TO_RIGHT : Layout.DIR_RIGHT_TO_LEFT;
+ return result;
+ }
+
+ private native static int runBidi(int dir, char[] chs, byte[] chInfo, int n, boolean haveInfo);
+}
\ No newline at end of file
diff --git a/core/java/android/text/AutoText.java b/core/java/android/text/AutoText.java
index 862305b..04730ec 100644
--- a/core/java/android/text/AutoText.java
+++ b/core/java/android/text/AutoText.java
@@ -18,7 +18,9 @@
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
+
import android.view.View;
import org.xmlpull.v1.XmlPullParser;
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 33ecc01..07e71f9 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -46,7 +46,8 @@
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.util.Log;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
import java.io.IOException;
import java.io.StringReader;
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 7f87365..98605888c 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -22,10 +22,10 @@
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
+import android.util.Patterns;
import android.webkit.WebView;
import android.widget.TextView;
-import com.android.common.Patterns;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
diff --git a/common/java/com/android/common/Patterns.java b/core/java/android/util/Patterns.java
similarity index 99%
rename from common/java/com/android/common/Patterns.java
rename to core/java/android/util/Patterns.java
index 3b3b038..2ee6e8a 100644
--- a/common/java/com/android/common/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.common;
+package android.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 4f496d7..0fc70d5 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -27,7 +27,7 @@
import java.util.TimeZone;
import java.util.Date;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
/**
* A class containing utility methods related to time zones.
diff --git a/core/java/android/util/XmlPullAttributes.java b/core/java/android/util/XmlPullAttributes.java
index 8f855cd..ecedbe1 100644
--- a/core/java/android/util/XmlPullAttributes.java
+++ b/core/java/android/util/XmlPullAttributes.java
@@ -19,7 +19,8 @@
import org.xmlpull.v1.XmlPullParser;
import android.util.AttributeSet;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
/**
* Provides an implementation of AttributeSet on top of an XmlPullParser.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 679206d..03b569d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1819,7 +1819,8 @@
mContext = context;
mResources = context != null ? context.getResources() : null;
mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
- ++sInstanceCount;
+ // Used for debug only
+ //++sInstanceCount;
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@@ -2133,11 +2134,14 @@
View() {
}
+ // Used for debug only
+ /*
@Override
protected void finalize() throws Throwable {
super.finalize();
--sInstanceCount;
}
+ */
/**
* <p>
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 264b8c9..582ef3f 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -230,7 +230,8 @@
lt = new LatencyTimer(100, 1000);
}
- ++sInstanceCount;
+ // For debug only
+ //++sInstanceCount;
// Initialize the statics when this class is first instantiated. This is
// done here instead of in the static block because Zygote does not
@@ -258,11 +259,14 @@
mDensity = context.getResources().getDisplayMetrics().densityDpi;
}
+ // For debug only
+ /*
@Override
protected void finalize() throws Throwable {
super.finalize();
--sInstanceCount;
}
+ */
public static long getInstanceCount() {
return sInstanceCount;
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 2aba60b..6c58461 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -57,8 +57,12 @@
* {@link android.hardware.SensorManager SensorManager}). Use the default
* value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL
* SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
+ *
+ * This constructor is private since no one uses it and making it public would complicate
+ * things, since the lowpass filtering code depends on the actual sampling period, and there's
+ * no way to get the period from SensorManager based on the rate constant.
*/
- public WindowOrientationListener(Context context, int rate) {
+ private WindowOrientationListener(Context context, int rate) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -107,94 +111,179 @@
}
class SensorEventListenerImpl implements SensorEventListener {
+ // We work with all angles in degrees in this class.
+ private static final float RADIANS_TO_DEGREES = (float) (180 / Math.PI);
+
+ // Indices into SensorEvent.values
private static final int _DATA_X = 0;
private static final int _DATA_Y = 1;
private static final int _DATA_Z = 2;
- // Angle around x-asis that's considered almost too vertical. Beyond
- // this angle will not result in any orientation changes. f phone faces uses,
- // the device is leaning backward.
- private static final int PIVOT_UPPER = 65;
- // Angle about x-axis that's considered negative vertical. Beyond this
- // angle will not result in any orientation changes. If phone faces uses,
- // the device is leaning forward.
- private static final int PIVOT_LOWER = -10;
- static final int ROTATION_0 = 0;
- static final int ROTATION_90 = 1;
- static final int ROTATION_180 = 2;
- static final int ROTATION_270 = 3;
- int mRotation = ROTATION_0;
- // Threshold values defined for device rotation positions
- // follow order ROTATION_0 .. ROTATION_270
- final int THRESHOLDS[][][] = new int[][][] {
- {{60, 135}, {135, 225}, {225, 300}},
- {{0, 45}, {45, 135}, {135, 210}, {330, 360}},
- {{0, 45}, {45, 120}, {240, 315}, {315, 360}},
- {{0, 30}, {150, 225}, {225, 315}, {315, 360}}
+ // Internal aliases for the four orientation states. ROTATION_0 = default portrait mode,
+ // ROTATION_90 = left side of device facing the sky, etc.
+ private static final int ROTATION_0 = 0;
+ private static final int ROTATION_90 = 1;
+ private static final int ROTATION_180 = 2;
+ private static final int ROTATION_270 = 3;
+
+ // Current orientation state
+ private int mRotation = ROTATION_0;
+
+ // Mapping our internal aliases into actual Surface rotation values
+ private final int[] SURFACE_ROTATIONS = new int[] {Surface.ROTATION_0, Surface.ROTATION_90,
+ Surface.ROTATION_180, Surface.ROTATION_270};
+
+ // Threshold ranges of orientation angle to transition into other orientation states.
+ // The first list is for transitions from ROTATION_0, the next for ROTATION_90, etc.
+ // ROTATE_TO defines the orientation each threshold range transitions to, and must be kept
+ // in sync with this.
+ // The thresholds are nearly regular -- we generally transition about the halfway point
+ // between two states with a swing of 30 degreees for hysteresis. For ROTATION_180,
+ // however, we enforce stricter thresholds, pushing the thresholds 15 degrees closer to 180.
+ private final int[][][] THRESHOLDS = new int[][][] {
+ {{60, 165}, {165, 195}, {195, 300}},
+ {{0, 45}, {45, 165}, {165, 195}, {330, 360}},
+ {{0, 45}, {45, 135}, {225, 315}, {315, 360}},
+ {{0, 30}, {165, 195}, {195, 315}, {315, 360}}
};
- // Transform rotation ranges based on THRESHOLDS. This
- // has to be in step with THESHOLDS
- final int ROTATE_TO[][] = new int[][] {
- {ROTATION_270, ROTATION_180, ROTATION_90},
- {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0},
- {ROTATION_0, ROTATION_270, ROTATION_90, ROTATION_0},
- {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0}
+ // See THRESHOLDS
+ private final int[][] ROTATE_TO = new int[][] {
+ {ROTATION_270, ROTATION_180, ROTATION_90},
+ {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0},
+ {ROTATION_0, ROTATION_270, ROTATION_90, ROTATION_0},
+ {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0}
};
- // Mapping into actual Surface rotation values
- final int TRANSFORM_ROTATIONS[] = new int[]{Surface.ROTATION_0,
- Surface.ROTATION_90, Surface.ROTATION_180, Surface.ROTATION_270};
+ // Maximum absolute tilt angle at which to consider orientation changes. Beyond this (i.e.
+ // when screen is facing the sky or ground), we refuse to make any orientation changes.
+ private static final int MAX_TILT = 65;
+
+ // Additional limits on tilt angle to transition to each new orientation. We ignore all
+ // vectors with tilt beyond MAX_TILT, but we can set stricter limits on transition to a
+ // particular orientation here.
+ private final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, MAX_TILT, 40, MAX_TILT};
+
+ // Between this tilt angle and MAX_TILT, we'll allow orientation changes, but we'll filter
+ // with a higher time constant, making us less sensitive to change. This primarily helps
+ // prevent momentary orientation changes when placing a device on a table from the side (or
+ // picking one up).
+ private static final int PARTIAL_TILT = 45;
+
+ // Maximum allowable deviation of the magnitude of the sensor vector from that of gravity,
+ // in m/s^2. Beyond this, we assume the phone is under external forces and we can't trust
+ // the sensor data. However, under constantly vibrating conditions (think car mount), we
+ // still want to pick up changes, so rather than ignore the data, we filter it with a very
+ // high time constant.
+ private static final int MAX_DEVIATION_FROM_GRAVITY = 1;
+
+ // Actual sampling period corresponding to SensorManager.SENSOR_DELAY_NORMAL. There's no
+ // way to get this information from SensorManager.
+ // Note the actual period is generally 3-30ms larger than this depending on the device, but
+ // that's not enough to significantly skew our results.
+ private static final int SAMPLING_PERIOD_MS = 200;
+
+ // The following time constants are all used in low-pass filtering the accelerometer output.
+ // See http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization for
+ // background.
+
+ // When device is near-vertical (screen approximately facing the horizon)
+ private static final int DEFAULT_TIME_CONSTANT_MS = 200;
+ // When device is partially tilted towards the sky or ground
+ private static final int TILTED_TIME_CONSTANT_MS = 600;
+ // When device is under external acceleration, i.e. not just gravity. We heavily distrust
+ // such readings.
+ private static final int ACCELERATING_TIME_CONSTANT_MS = 5000;
+
+ private static final float DEFAULT_LOWPASS_ALPHA =
+ (float) SAMPLING_PERIOD_MS / (DEFAULT_TIME_CONSTANT_MS + SAMPLING_PERIOD_MS);
+ private static final float TILTED_LOWPASS_ALPHA =
+ (float) SAMPLING_PERIOD_MS / (TILTED_TIME_CONSTANT_MS + SAMPLING_PERIOD_MS);
+ private static final float ACCELERATING_LOWPASS_ALPHA =
+ (float) SAMPLING_PERIOD_MS / (ACCELERATING_TIME_CONSTANT_MS + SAMPLING_PERIOD_MS);
+
+ // The low-pass filtered accelerometer data
+ private float[] mFilteredVector = new float[] {0, 0, 0};
int getCurrentRotation() {
- return TRANSFORM_ROTATIONS[mRotation];
+ return SURFACE_ROTATIONS[mRotation];
}
-
- private void calculateNewRotation(int orientation, int zyangle) {
- if (localLOGV) Log.i(TAG, orientation + ", " + zyangle + ", " + mRotation);
- int rangeArr[][] = THRESHOLDS[mRotation];
+
+ private void calculateNewRotation(int orientation, int tiltAngle) {
+ if (localLOGV) Log.i(TAG, orientation + ", " + tiltAngle + ", " + mRotation);
+ int thresholdRanges[][] = THRESHOLDS[mRotation];
int row = -1;
- for (int i = 0; i < rangeArr.length; i++) {
- if ((orientation >= rangeArr[i][0]) && (orientation < rangeArr[i][1])) {
+ for (int i = 0; i < thresholdRanges.length; i++) {
+ if (orientation >= thresholdRanges[i][0] && orientation < thresholdRanges[i][1]) {
row = i;
break;
}
}
- if (row != -1) {
- // Find new rotation based on current rotation value.
- // This also takes care of irregular rotations as well.
- int rotation = ROTATE_TO[mRotation][row];
- if (localLOGV) Log.i(TAG, " new rotation = " + rotation);
- if (rotation != mRotation) {
- mRotation = rotation;
- // Trigger orientation change
- onOrientationChanged(TRANSFORM_ROTATIONS[rotation]);
- }
+ if (row == -1) return; // no matching transition
+
+ int rotation = ROTATE_TO[mRotation][row];
+ if (tiltAngle > MAX_TRANSITION_TILT[rotation]) {
+ // tilted too far flat to go to this rotation
+ return;
}
+
+ if (localLOGV) Log.i(TAG, " new rotation = " + rotation);
+ mRotation = rotation;
+ onOrientationChanged(SURFACE_ROTATIONS[rotation]);
+ }
+
+ private float lowpassFilter(float newValue, float oldValue, float alpha) {
+ return alpha * newValue + (1 - alpha) * oldValue;
+ }
+
+ private float vectorMagnitude(float x, float y, float z) {
+ return (float) Math.sqrt(x*x + y*y + z*z);
+ }
+
+ /**
+ * Absolute angle between upVector and the x-y plane (the plane of the screen), in [0, 90].
+ * 90 degrees = screen facing the sky or ground.
+ */
+ private float tiltAngle(float z, float magnitude) {
+ return Math.abs((float) Math.asin(z / magnitude) * RADIANS_TO_DEGREES);
}
public void onSensorChanged(SensorEvent event) {
- float[] values = event.values;
- float X = values[_DATA_X];
- float Y = values[_DATA_Y];
- float Z = values[_DATA_Z];
- float OneEightyOverPi = 57.29577957855f;
- float gravity = (float) Math.sqrt(X*X+Y*Y+Z*Z);
- float zyangle = (float)Math.asin(Z/gravity)*OneEightyOverPi;
- if ((zyangle <= PIVOT_UPPER) && (zyangle >= PIVOT_LOWER)) {
- // Check orientation only if the phone is flat enough
- // Don't trust the angle if the magnitude is small compared to the y value
- float angle = (float)Math.atan2(Y, -X) * OneEightyOverPi;
- int orientation = 90 - Math.round(angle);
- // normalize to 0 - 359 range
- while (orientation >= 360) {
- orientation -= 360;
- }
- while (orientation < 0) {
- orientation += 360;
- }
- calculateNewRotation(orientation, Math.round(zyangle));
+ // the vector given in the SensorEvent points straight up (towards the sky) under ideal
+ // conditions (the phone is not accelerating). i'll call this upVector elsewhere.
+ float x = event.values[_DATA_X];
+ float y = event.values[_DATA_Y];
+ float z = event.values[_DATA_Z];
+ float magnitude = vectorMagnitude(x, y, z);
+ float deviation = Math.abs(magnitude - SensorManager.STANDARD_GRAVITY);
+ float tiltAngle = tiltAngle(z, magnitude);
+
+ float alpha = DEFAULT_LOWPASS_ALPHA;
+ if (tiltAngle > MAX_TILT) {
+ return;
+ } else if (deviation > MAX_DEVIATION_FROM_GRAVITY) {
+ alpha = ACCELERATING_LOWPASS_ALPHA;
+ } else if (tiltAngle > PARTIAL_TILT) {
+ alpha = TILTED_LOWPASS_ALPHA;
}
+
+ x = mFilteredVector[0] = lowpassFilter(x, mFilteredVector[0], alpha);
+ y = mFilteredVector[1] = lowpassFilter(y, mFilteredVector[1], alpha);
+ z = mFilteredVector[2] = lowpassFilter(z, mFilteredVector[2], alpha);
+ magnitude = vectorMagnitude(x, y, z);
+ tiltAngle = tiltAngle(z, magnitude);
+
+ // Angle between the x-y projection of upVector and the +y-axis, increasing
+ // counter-clockwise.
+ // 0 degrees = speaker end towards the sky
+ // 90 degrees = left edge of device towards the sky
+ float orientationAngle = (float) Math.atan2(-x, y) * RADIANS_TO_DEGREES;
+ int orientation = Math.round(orientationAngle);
+ // atan2 returns (-180, 180]; normalize to [0, 360)
+ if (orientation < 0) {
+ orientation += 360;
+ }
+ calculateNewRotation(orientation, Math.round(tiltAngle));
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
@@ -208,13 +297,12 @@
public boolean canDetectOrientation() {
return mSensor != null;
}
-
+
/**
* Called when the rotation view of the device has changed.
- * Can be either Surface.ROTATION_90 or Surface.ROTATION_0.
- * @param rotation The new orientation of the device.
*
- * @see #ORIENTATION_UNKNOWN
+ * @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants.
+ * @see Surface
*/
abstract public void onOrientationChanged(int rotation);
}
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 87cab3c..647556b 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.net.http.Headers;
+import android.net.http.HttpDateTime;
import android.os.FileUtils;
import android.util.Log;
import java.io.File;
@@ -30,7 +31,6 @@
import java.util.ArrayList;
import java.util.Map;
-import com.android.common.HttpDateTime;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 84e34bc..1d28731 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -18,9 +18,9 @@
import android.net.ParseException;
import android.net.WebAddress;
+import android.net.http.HttpDateTime;
import android.util.Log;
-import com.android.common.HttpDateTime;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 662be95..8981419 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -173,6 +173,9 @@
private long mAppCacheMaxSize = Long.MAX_VALUE;
private String mAppCachePath = "";
private String mDatabasePath = "";
+ // The WebCore DatabaseTracker only allows the database path to be set
+ // once. Keep track of when the path has been set.
+ private boolean mDatabasePathHasBeenSet = false;
private String mGeolocationDatabasePath = "";
// Don't need to synchronize the get/set methods as they
// are basic types, also none of these values are used in
@@ -1006,13 +1009,15 @@
/**
* Set the path to where database storage API databases should be saved.
+ * Nota that the WebCore Database Tracker only allows the path to be set once.
* This will update WebCore when the Sync runs in the C++ side.
* @param databasePath String path to the directory where databases should
* be saved. May be the empty string but should never be null.
*/
public synchronized void setDatabasePath(String databasePath) {
- if (databasePath != null && !databasePath.equals(mDatabasePath)) {
+ if (databasePath != null && !mDatabasePathHasBeenSet) {
mDatabasePath = databasePath;
+ mDatabasePathHasBeenSet = true;
postSync();
}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c1a4a49..d29d6f3 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3136,7 +3136,8 @@
}
private void drawExtras(Canvas canvas, int extras) {
- if (mNativeClass == 0) return;
+ // If mNativeClass is 0, we should not reach here, so we do not
+ // need to check it again.
// Currently for each draw we compute the animation values;
// We may in the future decide to do that independently.
if (nativeEvaluateLayersAnimations()) {
@@ -3153,7 +3154,6 @@
if (mDrawHistory) {
canvas.scale(mActualScale, mActualScale);
canvas.drawPicture(mHistoryPicture);
- drawExtras(canvas, DRAW_EXTRAS_NONE);
return;
}
@@ -3369,6 +3369,7 @@
if (isTextView) {
rebuildWebTextView();
if (inEditingMode()) {
+ mWebTextView.setDefaultSelection();
imm.showSoftInput(mWebTextView, 0);
if (zoom) {
didUpdateTextViewBounds(true);
@@ -3686,6 +3687,7 @@
// might be. Check it, and if so, hand over to the WebTextView.
rebuildWebTextView();
if (inEditingMode()) {
+ mWebTextView.setDefaultSelection();
return mWebTextView.dispatchKeyEvent(event);
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9ddfeff..bec62b1 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -467,6 +467,18 @@
// True when the popup should be hidden because of a call to
// dispatchDisplayHint()
private boolean mPopupHidden;
+
+ /**
+ * ID of the active pointer. This is used to retain consistency during
+ * drags/flings if multiple pointers are used.
+ */
+ private int mActivePointerId = INVALID_POINTER;
+
+ /**
+ * Sentinel value for no current active pointer.
+ * Used by {@link #mActivePointerId}.
+ */
+ private static final int INVALID_POINTER = -1;
/**
* Interface definition for a callback to be invoked when the list or grid
@@ -1995,8 +2007,6 @@
}
final int action = ev.getAction();
- final int x = (int) ev.getX();
- final int y = (int) ev.getY();
View v;
int deltaY;
@@ -2006,18 +2016,22 @@
}
mVelocityTracker.addMovement(ev);
- switch (action) {
+ switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
switch (mTouchMode) {
case TOUCH_MODE_OVERFLING: {
mFlingRunnable.endFling();
mTouchMode = TOUCH_MODE_OVERSCROLL;
- mLastY = y;
+ mLastY = (int) ev.getY();
mMotionCorrection = 0;
+ mActivePointerId = ev.getPointerId(0);
break;
}
default: {
+ mActivePointerId = ev.getPointerId(0);
+ final int x = (int) ev.getX();
+ final int y = (int) ev.getY();
int motionPosition = pointToPosition(x, y);
if (!mDataChanged) {
if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
@@ -2037,12 +2051,15 @@
// code in ViewRoot to try to find a nearby view to select
return false;
}
- // User clicked on whitespace, or stopped a fling. It is a scroll.
- createScrollingCache();
- mTouchMode = TOUCH_MODE_SCROLL;
- mMotionCorrection = 0;
- motionPosition = findMotionRow(y);
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+
+ if (mTouchMode == TOUCH_MODE_FLING) {
+ // Stopped a fling. It is a scroll.
+ createScrollingCache();
+ mTouchMode = TOUCH_MODE_SCROLL;
+ mMotionCorrection = 0;
+ motionPosition = findMotionRow(y);
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ }
}
}
@@ -2062,6 +2079,8 @@
}
case MotionEvent.ACTION_MOVE: {
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ final int y = (int) ev.getY(pointerIndex);
deltaY = y - mMotionY;
switch (mTouchMode) {
case TOUCH_MODE_DOWN:
@@ -2142,7 +2161,7 @@
// We did not scroll the full amount. Treat this essentially like the
// start of a new touch scroll
- final int motionPosition = findMotionRow(y);
+ final int motionPosition = findClosestMotionRow(y);
mMotionCorrection = 0;
motionView = getChildAt(motionPosition - mFirstPosition);
@@ -2238,7 +2257,7 @@
} else {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int initialVelocity = (int) velocityTracker.getYVelocity();
+ final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
if (Math.abs(initialVelocity) > mMinimumVelocity) {
if (mFlingRunnable == null) {
@@ -2264,7 +2283,7 @@
}
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int initialVelocity = (int) velocityTracker.getYVelocity();
+ final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
if (Math.abs(initialVelocity) > mMinimumVelocity) {
@@ -2290,6 +2309,8 @@
mVelocityTracker.recycle();
mVelocityTracker = null;
}
+
+ mActivePointerId = INVALID_POINTER;
if (PROFILE_SCROLLING) {
if (mScrollProfilingStarted) {
@@ -2332,6 +2353,24 @@
mVelocityTracker = null;
}
}
+
+ mActivePointerId = INVALID_POINTER;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ onSecondaryPointerUp(ev);
+ final int x = mMotionX;
+ final int y = mMotionY;
+ final int motionPosition = pointToPosition(x, y);
+ if (motionPosition >= 0) {
+ // Remember where the motion event started
+ v = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = v.getTop();
+ mMotionPosition = motionPosition;
+ }
+ mLastY = y;
+ break;
}
}
@@ -2380,8 +2419,6 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
- int x = (int) ev.getX();
- int y = (int) ev.getY();
View v;
if (mFastScroller != null) {
@@ -2391,13 +2428,17 @@
}
}
- switch (action) {
+ switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
int touchMode = mTouchMode;
if (touchMode == TOUCH_MODE_OVERFLING || touchMode == TOUCH_MODE_OVERSCROLL) {
return true;
}
+ final int x = (int) ev.getX();
+ final int y = (int) ev.getY();
+ mActivePointerId = ev.getPointerId(0);
+
int motionPosition = findMotionRow(y);
if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) {
// User clicked on an actual view (and was not stopping a fling).
@@ -2420,6 +2461,8 @@
case MotionEvent.ACTION_MOVE: {
switch (mTouchMode) {
case TOUCH_MODE_DOWN:
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ final int y = (int) ev.getY(pointerIndex);
if (startScrollIfNeeded(y - mMotionY)) {
return true;
}
@@ -2430,13 +2473,37 @@
case MotionEvent.ACTION_UP: {
mTouchMode = TOUCH_MODE_REST;
+ mActivePointerId = INVALID_POINTER;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
break;
}
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ onSecondaryPointerUp(ev);
+ break;
+ }
}
return false;
}
+
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+ MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ // TODO: Make this decision more intelligent.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mMotionX = (int) ev.getX(newPointerIndex);
+ mMotionY = (int) ev.getY(newPointerIndex);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
/**
* {@inheritDoc}
@@ -3150,9 +3217,25 @@
* Find the row closest to y. This row will be used as the motion row when scrolling
*
* @param y Where the user touched
- * @return The position of the first (or only) item in the row closest to y
+ * @return The position of the first (or only) item in the row containing y
*/
abstract int findMotionRow(int y);
+
+ /**
+ * Find the row closest to y. This row will be used as the motion row when scrolling.
+ *
+ * @param y Where the user touched
+ * @return The position of the first (or only) item in the row closest to y
+ */
+ int findClosestMotionRow(int y) {
+ final int childCount = getChildCount();
+ if (childCount == 0) {
+ return INVALID_POSITION;
+ }
+
+ final int motionRow = findMotionRow(y);
+ return motionRow != INVALID_POSITION ? motionRow : mFirstPosition + childCount - 1;
+ }
/**
* Causes all the views to be rebuilt and redrawn.
@@ -4072,9 +4155,9 @@
final View[] activeViews = mActiveViews;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
- AbsListView.LayoutParams lp = (AbsListView.LayoutParams)child.getLayoutParams();
+ AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
// Don't put header or footer views into the scrap heap
- if (lp != null && lp.viewType != AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
+ if (lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
// Note: We do place AdapterView.ITEM_VIEW_TYPE_IGNORE in active views.
// However, we will NOT place them into scrap views.
activeViews[i] = child;
diff --git a/core/java/android/widget/ExpandableListConnector.java b/core/java/android/widget/ExpandableListConnector.java
index ccce7c1..9c43e9b 100644
--- a/core/java/android/widget/ExpandableListConnector.java
+++ b/core/java/android/widget/ExpandableListConnector.java
@@ -25,7 +25,6 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
/*
* Implementation notes:
@@ -637,7 +636,7 @@
// Check to see if it's already expanded
if (posMetadata.groupMetadata != null) return false;
- /* Restrict number of exp groups to mMaxExpGroupCount */
+ /* Restrict number of expanded groups to mMaxExpGroupCount */
if (mExpGroupMetadataList.size() >= mMaxExpGroupCount) {
/* Collapse a group */
// TODO: Collapse something not on the screen instead of the first one?
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index b9acf5e..9e930a5 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -431,8 +431,6 @@
}
}
}
-
- return mFirstPosition + childCount - 1;
}
return INVALID_POSITION;
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index a7b819a..acb7e02 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -116,7 +116,19 @@
private int mTouchSlop;
private int mMinimumVelocity;
private int mMaximumVelocity;
-
+
+ /**
+ * ID of the active pointer. This is used to retain consistency during
+ * drags/flings if multiple pointers are used.
+ */
+ private int mActivePointerId = INVALID_POINTER;
+
+ /**
+ * Sentinel value for no current active pointer.
+ * Used by {@link #mActivePointerId}.
+ */
+ private static final int INVALID_POINTER = -1;
+
public HorizontalScrollView(Context context) {
this(context, null);
}
@@ -362,6 +374,17 @@
return handled;
}
+ private boolean inChild(int x, int y) {
+ if (getChildCount() > 0) {
+ final View child = getChildAt(0);
+ return !(y < child.getTop()
+ || y >= child.getBottom()
+ || x < child.getLeft()
+ || x >= child.getRight());
+ }
+ return false;
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
@@ -380,10 +403,8 @@
return true;
}
- final float x = ev.getX();
-
- switch (action) {
- case MotionEvent.ACTION_MOVE:
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_MOVE: {
/*
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
@@ -393,16 +414,30 @@
* Locally do absolute value. mLastMotionX is set to the x value
* of the down event.
*/
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float x = ev.getX(pointerIndex);
final int xDiff = (int) Math.abs(x - mLastMotionX);
if (xDiff > mTouchSlop) {
mIsBeingDragged = true;
+ mLastMotionX = x;
if (mParent != null) mParent.requestDisallowInterceptTouchEvent(true);
}
break;
+ }
- case MotionEvent.ACTION_DOWN:
- /* Remember location of down touch */
+ case MotionEvent.ACTION_DOWN: {
+ final float x = ev.getX();
+ if (!inChild((int) x, (int) ev.getY())) {
+ mIsBeingDragged = false;
+ break;
+ }
+
+ /*
+ * Remember location of down touch.
+ * ACTION_DOWN always refers to pointer index 0.
+ */
mLastMotionX = x;
+ mActivePointerId = ev.getPointerId(0);
/*
* If being flinged and user touches the screen, initiate drag;
@@ -411,11 +446,16 @@
*/
mIsBeingDragged = !mScroller.isFinished();
break;
+ }
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
/* Release the drag */
mIsBeingDragged = false;
+ mActivePointerId = INVALID_POINTER;
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
break;
}
@@ -441,10 +481,9 @@
mVelocityTracker.addMovement(ev);
final int action = ev.getAction();
- final float x = ev.getX();
- switch (action) {
- case MotionEvent.ACTION_DOWN:
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
@@ -452,42 +491,78 @@
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
+
+ final float x = ev.getX();
+ if (!(mIsBeingDragged = inChild((int) x, (int) ev.getY()))) {
+ return false;
+ }
// Remember where the motion event started
mLastMotionX = x;
break;
+ }
case MotionEvent.ACTION_MOVE:
- // Scroll to follow the motion event
- final int deltaX = (int) (mLastMotionX - x);
- mLastMotionX = x;
+ if (mIsBeingDragged) {
+ // Scroll to follow the motion event
+ final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float x = ev.getX(activePointerIndex);
+ final int deltaX = (int) (mLastMotionX - x);
+ mLastMotionX = x;
- overscrollBy(deltaX, 0, mScrollX, 0, getScrollRange(), 0,
- getOverscrollMax(), 0);
+ overscrollBy(deltaX, 0, mScrollX, 0, getScrollRange(), 0,
+ getOverscrollMax(), 0);
+ }
break;
case MotionEvent.ACTION_UP:
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- int initialVelocity = (int) velocityTracker.getXVelocity();
+ if (mIsBeingDragged) {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
- if (getChildCount() > 0) {
- if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
- fling(-initialVelocity);
- } else {
- final int right = getScrollRange();
- if (mScroller.springback(mScrollX, mScrollY, 0, 0, right, 0)) {
- invalidate();
+ if (getChildCount() > 0) {
+ if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+ fling(-initialVelocity);
+ } else {
+ final int right = getScrollRange();
+ if (mScroller.springback(mScrollX, mScrollY, 0, 0, right, 0)) {
+ invalidate();
+ }
}
}
- }
+
+ mActivePointerId = INVALID_POINTER;
+ mIsBeingDragged = false;
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
}
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ break;
}
return true;
}
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+ MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ // TODO: Make this decision more intelligent.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastMotionX = ev.getX(newPointerIndex);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
@Override
protected void onOverscrolled(int scrollX, int scrollY,
boolean clampedX, boolean clampedY) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 4bd3a82..bd07e1f 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -632,6 +632,8 @@
final boolean baselineAligned = mBaselineAligned;
final boolean useLargestChild = mUseLargestChild;
+
+ final boolean isExactly = widthMode == MeasureSpec.EXACTLY;
int largestChildWidth = Integer.MIN_VALUE;
@@ -658,7 +660,13 @@
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
- mTotalLength += lp.leftMargin + lp.rightMargin;
+ if (isExactly) {
+ mTotalLength += lp.leftMargin + lp.rightMargin;
+ } else {
+ final int totalLength = mTotalLength;
+ mTotalLength = Math.max(totalLength, totalLength +
+ lp.leftMargin + lp.rightMargin);
+ }
// Baseline alignment requires to measure widgets to obtain the
// baseline offset (in particular for TextViews). The following
@@ -694,8 +702,14 @@
}
final int childWidth = child.getMeasuredWidth();
- mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
- getNextLocationOffset(child);
+ if (isExactly) {
+ mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
+ getNextLocationOffset(child);
+ } else {
+ final int totalLength = mTotalLength;
+ mTotalLength = Math.max(totalLength, totalLength + childWidth + lp.leftMargin +
+ lp.rightMargin + getNextLocationOffset(child));
+ }
if (useLargestChild) {
largestChildWidth = Math.max(childWidth, largestChildWidth);
@@ -780,8 +794,14 @@
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
child.getLayoutParams();
- mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin +
- getNextLocationOffset(child);
+ if (isExactly) {
+ mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin +
+ getNextLocationOffset(child);
+ } else {
+ final int totalLength = mTotalLength;
+ mTotalLength = Math.max(totalLength, totalLength + largestChildWidth +
+ lp.leftMargin + lp.rightMargin + getNextLocationOffset(child));
+ }
}
}
@@ -851,8 +871,14 @@
}
}
- mTotalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin +
- getNextLocationOffset(child);
+ if (isExactly) {
+ mTotalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin +
+ getNextLocationOffset(child);
+ } else {
+ final int totalLength = mTotalLength;
+ mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredWidth() +
+ lp.leftMargin + lp.rightMargin + getNextLocationOffset(child));
+ }
boolean matchHeightLocally = heightMode != MeasureSpec.EXACTLY &&
lp.height == LayoutParams.MATCH_PARENT;
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 8d688a5..912dd5e 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -138,7 +138,7 @@
// the single allocated result per list view; kinda cheesey but avoids
// allocating these thingies too often.
- private ArrowScrollFocusResult mArrowScrollFocusResult = new ArrowScrollFocusResult();
+ private final ArrowScrollFocusResult mArrowScrollFocusResult = new ArrowScrollFocusResult();
public ListView(Context context) {
this(context, null);
@@ -1040,7 +1040,8 @@
childWidth = child.getMeasuredWidth();
childHeight = child.getMeasuredHeight();
- if (recycleOnMeasure()) {
+ if (recycleOnMeasure() && mRecycler.shouldRecycleViewType(
+ ((LayoutParams) child.getLayoutParams()).viewType)) {
mRecycler.addScrapView(child);
}
}
@@ -1155,7 +1156,8 @@
}
// Recycle the view before we possibly return from the method
- if (recyle) {
+ if (recyle && recycleBin.shouldRecycleViewType(
+ ((LayoutParams) child.getLayoutParams()).viewType)) {
recycleBin.addScrapView(child);
}
@@ -1192,7 +1194,6 @@
return mFirstPosition + i;
}
}
- return mFirstPosition + childCount - 1;
}
return INVALID_POSITION;
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 6dc9f78..202e658 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -696,8 +696,7 @@
* <p>Start the indeterminate progress animation.</p>
*/
void startAnimation() {
- int visibility = getVisibility();
- if (visibility != VISIBLE) {
+ if (getVisibility() != VISIBLE) {
return;
}
@@ -771,7 +770,7 @@
// let's be nice with the UI thread
if (v == GONE || v == INVISIBLE) {
stopAnimation();
- } else if (v == VISIBLE) {
+ } else {
startAnimation();
}
}
@@ -779,6 +778,20 @@
}
@Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+
+ if (mIndeterminate) {
+ // let's be nice with the UI thread
+ if (visibility == GONE || visibility == INVISIBLE) {
+ stopAnimation();
+ } else {
+ startAnimation();
+ }
+ }
+ }
+
+ @Override
public void invalidateDrawable(Drawable dr) {
if (!mInDrawing) {
if (verifyDrawable(dr)) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index fd24058..489c44d 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -427,7 +427,7 @@
case MotionEvent.ACTION_DOWN: {
final float y = ev.getY();
- if (!inChild((int)ev.getX(), (int)y)) {
+ if (!inChild((int) ev.getX(), (int) y)) {
mIsBeingDragged = false;
break;
}
@@ -493,7 +493,7 @@
}
final float y = ev.getY();
- if (!(mIsBeingDragged = inChild((int)ev.getX(), (int)y))) {
+ if (!(mIsBeingDragged = inChild((int) ev.getX(), (int) y))) {
return false;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 951563a..51e1c57 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2823,9 +2823,6 @@
* Null means to use the normal empty text. The hint does not currently
* participate in determining the size of the view.
*
- * This method is deprecated. Use {link #setHint(int, String)} or
- * {link #setHint(CharSequence, String)} instead.
- *
* @attr ref android.R.styleable#TextView_hint
*/
@android.view.RemotableViewMethod
@@ -2845,9 +2842,6 @@
* Sets the text to be displayed when the text of the TextView is empty,
* from a resource.
*
- * This method is deprecated. Use {link #setHint(int, String)} or
- * {link #setHint(CharSequence, String)} instead.
- *
* @attr ref android.R.styleable#TextView_hint
*/
@android.view.RemotableViewMethod
diff --git a/core/java/com/android/internal/content/SyncStateContentProviderHelper.java b/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
index cd6a9a1..274082c 100644
--- a/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
+++ b/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
@@ -50,6 +50,11 @@
public static final String PATH = "syncstate";
+ private static final String QUERY_COUNT_SYNC_STATE_ROWS =
+ "SELECT count(*)"
+ + " FROM " + SYNC_STATE_TABLE
+ + " WHERE " + SyncStateContract.Columns._ID + "=?";
+
public void createDatabase(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_TABLE);
db.execSQL("CREATE TABLE " + SYNC_STATE_TABLE + " ("
@@ -96,11 +101,17 @@
return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
}
- public void update(SQLiteDatabase db, long rowId, Object data) {
+ public int update(SQLiteDatabase db, long rowId, Object data) {
+ if (DatabaseUtils.longForQuery(db, QUERY_COUNT_SYNC_STATE_ROWS,
+ new String[]{Long.toString(rowId)}) < 1) {
+ return 0;
+ }
db.execSQL("UPDATE " + SYNC_STATE_TABLE
+ " SET " + SyncStateContract.Columns.DATA + "=?"
+ " WHERE " + SyncStateContract.Columns._ID + "=" + rowId,
new Object[]{data});
+ // assume a row was modified since we know it exists
+ return 1;
}
public void onAccountsChanged(SQLiteDatabase db, Account[] accounts) {
diff --git a/common/java/com/android/common/DNParser.java b/core/java/com/android/internal/net/DNParser.java
similarity index 99%
rename from common/java/com/android/common/DNParser.java
rename to core/java/com/android/internal/net/DNParser.java
index 32d57c0..5254207 100644
--- a/common/java/com/android/common/DNParser.java
+++ b/core/java/com/android/internal/net/DNParser.java
@@ -15,7 +15,8 @@
* limitations under the License.
*/
-package com.android.common;
+package com.android.internal.net;
+
import android.util.Log;
@@ -34,6 +35,8 @@
*
* <p>This class is used by {@link DomainNameValidator} only. However, in order to make this
* class visible from unit tests, it's made public.
+ *
+ * @hide
*/
public final class DNParser {
private static final String TAG = "DNParser";
diff --git a/common/java/com/android/common/DomainNameValidator.java b/core/java/com/android/internal/net/DomainNameValidator.java
similarity index 99%
rename from common/java/com/android/common/DomainNameValidator.java
rename to core/java/com/android/internal/net/DomainNameValidator.java
index 25dc007..dbd5019 100644
--- a/common/java/com/android/common/DomainNameValidator.java
+++ b/core/java/com/android/internal/net/DomainNameValidator.java
@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.common;
+package com.android.internal.net;
+
import android.util.Config;
import android.util.Log;
@@ -30,6 +31,7 @@
import javax.security.auth.x500.X500Principal;
+/** @hide */
public class DomainNameValidator {
private final static String TAG = "DomainNameValidator";
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 9e5bdff..2369d25 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -20,7 +20,7 @@
import android.content.Context;
import android.content.res.XmlResourceParser;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/common/java/com/android/common/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java
similarity index 99%
rename from common/java/com/android/common/FastXmlSerializer.java
rename to core/java/com/android/internal/util/FastXmlSerializer.java
index 0d33941..592a8fa 100644
--- a/common/java/com/android/common/FastXmlSerializer.java
+++ b/core/java/com/android/internal/util/FastXmlSerializer.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.common;
+package com.android.internal.util;
import org.xmlpull.v1.XmlSerializer;
diff --git a/common/java/com/android/common/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
similarity index 99%
rename from common/java/com/android/common/XmlUtils.java
rename to core/java/com/android/internal/util/XmlUtils.java
index dd57e49..8d8df16 100644
--- a/common/java/com/android/common/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.common;
+package com.android.internal.util;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 9713c27f..1956b4e 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -17,15 +17,20 @@
package com.android.internal.widget;
import android.app.DevicePolicyManager;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.security.MessageDigest;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import android.widget.Button;
+import com.android.internal.R;
+import com.android.internal.telephony.ITelephony;
import com.google.android.collect.Lists;
import java.io.FileNotFoundException;
@@ -675,4 +680,43 @@
|| (mode == MODE_PIN || mode == MODE_PASSWORD) && savedPasswordExists();
return secure;
}
+
+ /**
+ * Sets the text on the emergency button to indicate what action will be taken.
+ * If there's currently a call in progress, the button will take them to the call
+ * @param button the button to update
+ */
+ public void updateEmergencyCallButtonState(Button button) {
+ int newState = TelephonyManager.getDefault().getCallState();
+ int textId;
+ if (newState == TelephonyManager.CALL_STATE_OFFHOOK) {
+ // show "return to call" text and show phone icon
+ textId = R.string.lockscreen_return_to_call;
+ int phoneCallIcon = R.drawable.stat_sys_phone_call;
+ button.setCompoundDrawablesWithIntrinsicBounds(phoneCallIcon, 0, 0, 0);
+ } else {
+ textId = R.string.lockscreen_emergency_call;
+ int emergencyIcon = R.drawable.ic_emergency;
+ button.setCompoundDrawablesWithIntrinsicBounds(emergencyIcon, 0, 0, 0);
+ }
+ button.setText(textId);
+ }
+
+ /**
+ * Resumes a call in progress. Typically launched from the EmergencyCall button
+ * on various lockscreens.
+ *
+ * @return true if we were able to tell InCallScreen to show.
+ */
+ public boolean resumeCall() {
+ ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+ try {
+ if (phone != null && phone.showCallScreen()) {
+ return true;
+ }
+ } catch (RemoteException e) {
+ // What can we do?
+ }
+ return false;
+ }
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index e8749ed..85d1a6f 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -45,6 +45,7 @@
android_view_Surface.cpp \
android_view_ViewRoot.cpp \
android_text_AndroidCharacter.cpp \
+ android_text_AndroidBidi.cpp \
android_text_KeyCharacterMap.cpp \
android_os_Debug.cpp \
android_os_FileUtils.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7c8df03..8586aca 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -142,6 +142,7 @@
extern int register_android_net_wifi_WifiManager(JNIEnv* env);
extern int register_android_security_Md5MessageDigest(JNIEnv *env);
extern int register_android_text_AndroidCharacter(JNIEnv *env);
+extern int register_android_text_AndroidBidi(JNIEnv *env);
extern int register_android_text_KeyCharacterMap(JNIEnv *env);
extern int register_android_opengl_classes(JNIEnv *env);
extern int register_android_bluetooth_HeadsetBase(JNIEnv* env);
@@ -1184,6 +1185,7 @@
REG_JNI(register_android_emoji_EmojiFactory),
REG_JNI(register_android_security_Md5MessageDigest),
REG_JNI(register_android_text_AndroidCharacter),
+ REG_JNI(register_android_text_AndroidBidi),
REG_JNI(register_android_text_KeyCharacterMap),
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_Binder),
diff --git a/core/jni/android_text_AndroidBidi.cpp b/core/jni/android_text_AndroidBidi.cpp
new file mode 100644
index 0000000..7696bb3
--- /dev/null
+++ b/core/jni/android_text_AndroidBidi.cpp
@@ -0,0 +1,81 @@
+/* //device/libs/android_runtime/android_text_AndroidBidi.cpp
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "AndroidUnicode"
+
+#include <jni.h>
+#include <android_runtime/AndroidRuntime.h>
+#include "utils/misc.h"
+#include "utils/Log.h"
+#include "unicode/ubidi.h"
+
+namespace android {
+
+static void jniThrowException(JNIEnv* env, const char* exc, const char* msg = NULL)
+{
+ jclass excClazz = env->FindClass(exc);
+ LOG_ASSERT(excClazz, "Unable to find class %s", exc);
+
+ env->ThrowNew(excClazz, msg);
+}
+
+static jint runBidi(JNIEnv* env, jobject obj, jint dir, jcharArray chsArray,
+ jbyteArray infoArray, int n, jboolean haveInfo)
+{
+ // Parameters are checked on java side
+ // Failures from GetXXXArrayElements indicate a serious out-of-memory condition
+ // that we don't bother to report, we're probably dead anyway.
+ jint result = 0;
+ jchar* chs = env->GetCharArrayElements(chsArray, NULL);
+ if (chs != NULL) {
+ jbyte* info = env->GetByteArrayElements(infoArray, NULL);
+ if (info != NULL) {
+ UErrorCode status = U_ZERO_ERROR;
+ UBiDi* bidi = ubidi_openSized(n, 0, &status);
+ ubidi_setPara(bidi, chs, n, dir, NULL, &status);
+ if (U_SUCCESS(status)) {
+ for (int i = 0; i < n; ++i) {
+ info[i] = ubidi_getLevelAt(bidi, i);
+ }
+ result = ubidi_getParaLevel(bidi);
+ } else {
+ jniThrowException(env, "java/lang/RuntimeException", NULL);
+ }
+ ubidi_close(bidi);
+
+ env->ReleaseByteArrayElements(infoArray, info, 0);
+ }
+ env->ReleaseCharArrayElements(chsArray, chs, JNI_ABORT);
+ }
+ return result;
+}
+
+static JNINativeMethod gMethods[] = {
+ { "runBidi", "(I[C[BIZ)I",
+ (void*) runBidi }
+};
+
+int register_android_text_AndroidBidi(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/text/AndroidBidi");
+ LOG_ASSERT(clazz, "Cannot find android/text/AndroidBidi");
+
+ return AndroidRuntime::registerNativeMethods(env, "android/text/AndroidBidi",
+ gMethods, NELEM(gMethods));
+}
+
+}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5d561b8..1e11a99 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -138,6 +138,9 @@
closed. The default is 0. -->
<integer name="config_lidNavigationAccessibility">0</integer>
+ <!-- Indicate whether the SD card is accessible without removing the battery. -->
+ <bool name="config_batterySdCardAccessibility">false</bool>
+
<!-- Vibrator pattern for feedback about a long screen/key press -->
<integer-array name="config_longPressVibePattern">
<item>0</item>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5d2d272..b791bf8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1441,6 +1441,8 @@
<string name="lockscreen_pattern_instructions">Draw pattern to unlock</string>
<!-- Button at the bottom of the unlock screen to make an emergency call. -->
<string name="lockscreen_emergency_call">Emergency call</string>
+ <!-- Button at the bottom of the unlock screen that lets the user return to a call -->
+ <string name="lockscreen_return_to_call">Return to call</string>
<!-- Shown to confirm that the user entered their lock pattern correctly. -->
<string name="lockscreen_pattern_correct">Correct!</string>
<!-- On the unlock pattern screen, shown when the user enters the wrong lock pattern and must try again. -->
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 1fb9852..b0e2843 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -9,6 +9,8 @@
$(call all-java-files-under, src) \
src/android/os/IAidlTest.aidl
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
+
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_PACKAGE_NAME := FrameworksCoreTests
diff --git a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
index ccd0dae..da6036a 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
@@ -88,7 +88,38 @@
int resultDir = StaticLayout.bidi(dir, chs, chInfo, n, false);
{
- StringBuilder sb = new StringBuilder("xdirs:");
+ StringBuilder sb = new StringBuilder("info:");
+ for (int i = 0; i < n; ++i) {
+ sb.append(" ").append(String.valueOf(chInfo[i]));
+ }
+ Log.i("BIDI", sb.toString());
+ }
+
+ char[] resultLevelChars = new char[n];
+ for (int i = 0; i < n; ++i) {
+ resultLevelChars[i] = (char)('0' + chInfo[i]);
+ }
+ String resultLevels = new String(resultLevelChars);
+ assertEquals("direction", expectedDir, resultDir);
+ assertEquals("levels", expectedLevels, resultLevels);
+ }
+
+ @SmallTest
+ public void testNativeBidi() {
+ // native bidi returns levels, not simply directions
+ expectNativeBidi(REQ_DL, ALEF + BET + GIMEL + " abc", "1111222", R);
+ }
+
+ private void expectNativeBidi(int dir, String text,
+ String expectedLevels, int expectedDir) {
+ char[] chs = text.toCharArray();
+ int n = chs.length;
+ byte[] chInfo = new byte[n];
+
+ int resultDir = AndroidBidi.bidi(dir, chs, chInfo, n, false);
+
+ {
+ StringBuilder sb = new StringBuilder("info:");
for (int i = 0; i < n; ++i) {
sb.append(" ").append(String.valueOf(chInfo[i]));
}
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java
index 23a4cde..22bbabc 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListBasicTest.java
@@ -16,29 +16,28 @@
package android.widget.expandablelistview;
-import android.widget.expandablelistview.ExpandableListSimple;
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
import android.util.ExpandableListScenario;
import android.util.ListUtil;
import android.util.ExpandableListScenario.MyGroup;
-
-import java.util.List;
-
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
import android.view.KeyEvent;
+import android.view.View;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
-public class ExpandableListBasicTest extends ActivityInstrumentationTestCase<ExpandableListSimple> {
+import java.util.List;
+
+public class ExpandableListBasicTest extends ActivityInstrumentationTestCase2<ExpandableListSimple> {
private ExpandableListScenario mActivity;
private ExpandableListView mListView;
private ExpandableListAdapter mAdapter;
private ListUtil mListUtil;
public ExpandableListBasicTest() {
- super("com.android.frameworks.coretests",
- ExpandableListSimple.class);
+ super(ExpandableListSimple.class);
}
@Override
@@ -87,7 +86,6 @@
@MediumTest
public void testExpandedGroupMovement() {
-
// Expand the first group
mListUtil.arrowScrollToSelectedPosition(0);
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
@@ -125,5 +123,55 @@
assertFalse("The expanded state was given to the inserted group",
mListView.isGroupExpanded(0));
}
-
+
+ // Static utility method, shared by different ExpandableListView scenario.
+ static void checkGroupAndChildPositions(ExpandableListView elv,
+ ActivityInstrumentationTestCase2<? extends ExpandableListScenario> activityInstrumentation) {
+ // Add a position tester ContextMenu listener to the ExpandableListView
+ PositionTesterContextMenuListener menuListener = new PositionTesterContextMenuListener();
+ elv.setOnCreateContextMenuListener(menuListener);
+
+ ListUtil listUtil = new ListUtil(elv, activityInstrumentation.getInstrumentation());
+ ExpandableListAdapter adapter = elv.getExpandableListAdapter();
+ Instrumentation instrumentation = activityInstrumentation.getInstrumentation();
+
+ int index = elv.getHeaderViewsCount();
+ int groupCount = adapter.getGroupCount();
+ for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) {
+
+ // Expand group
+ assertFalse("Group is already expanded", elv.isGroupExpanded(groupIndex));
+ listUtil.arrowScrollToSelectedPosition(index);
+ instrumentation.waitForIdleSync();
+ activityInstrumentation.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ activityInstrumentation.getInstrumentation().waitForIdleSync();
+ assertTrue("Group did not expand " + groupIndex, elv.isGroupExpanded(groupIndex));
+
+ // Check group index in context menu
+ menuListener.expectGroupContextMenu(groupIndex);
+ // Make sure the group is visible so that getChild finds it
+ listUtil.arrowScrollToSelectedPosition(index);
+ View groupChild = elv.getChildAt(index - elv.getFirstVisiblePosition());
+ elv.showContextMenuForChild(groupChild);
+ index++;
+
+ final int childrenCount = adapter.getChildrenCount(groupIndex);
+ for (int childIndex = 0; childIndex < childrenCount; childIndex++) {
+ // Check child index in context menu
+ listUtil.arrowScrollToSelectedPosition(index);
+ menuListener.expectChildContextMenu(groupIndex, childIndex);
+ View child = elv.getChildAt(index - elv.getFirstVisiblePosition());
+ elv.showContextMenuForChild(child);
+ index++;
+ }
+ }
+
+ // Cleanup: remove the listener we added.
+ elv.setOnCreateContextMenuListener(null);
+ }
+
+ @MediumTest
+ public void testGroupChildPositions() {
+ checkGroupAndChildPositions(mListView, this);
+ }
}
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java
index 7965f9f..2251c1d 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeaders.java
@@ -16,13 +16,10 @@
package android.widget.expandablelistview;
-import android.util.ExpandableListScenario;
-
import android.os.Bundle;
+import android.util.ExpandableListScenario;
import android.widget.Button;
import android.widget.ExpandableListView;
-import android.widget.ListAdapter;
-import android.widget.ListView;
public class ExpandableListWithHeaders extends ExpandableListScenario {
private static final int[] sNumChildren = {1, 4, 3, 2, 6};
@@ -46,13 +43,13 @@
for (int i = 0; i < sNumOfHeadersAndFooters; i++) {
Button header = new Button(this);
- header.setText("Header View");
+ header.setText("Header View " + i);
expandableListView.addHeaderView(header);
}
for (int i = 0; i < sNumOfHeadersAndFooters; i++) {
Button footer = new Button(this);
- footer.setText("Footer View");
+ footer.setText("Footer View " + i);
expandableListView.addFooterView(footer);
}
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
index 50d0929..ca07e6b 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
@@ -16,22 +16,20 @@
package android.widget.expandablelistview;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.util.ListUtil;
import android.view.KeyEvent;
import android.widget.ExpandableListView;
-import android.widget.expandablelistview.ExpandableListWithHeaders;
-import android.util.ListUtil;
-
-public class ExpandableListWithHeadersTest extends ActivityInstrumentationTestCase<ExpandableListWithHeaders> {
+public class ExpandableListWithHeadersTest extends
+ ActivityInstrumentationTestCase2<ExpandableListWithHeaders> {
private ExpandableListView mExpandableListView;
private ListUtil mListUtil;
public ExpandableListWithHeadersTest() {
- super("com.android.frameworks.coretests",
- ExpandableListWithHeaders.class);
+ super(ExpandableListWithHeaders.class);
}
@Override
@@ -63,4 +61,9 @@
getInstrumentation().waitForIdleSync();
assertTrue(mExpandableListView.isGroupExpanded(0));
}
+
+ @MediumTest
+ public void testGroupChildPositions() {
+ ExpandableListBasicTest.checkGroupAndChildPositions(mExpandableListView, this);
+ }
}
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java b/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java
index 08b0d31..f4c9d56 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/InflatedExpandableListView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.widget.expandablelistview;
+package android.widget.expandablelistview;
import com.android.frameworks.coretests.R;
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/PositionTesterContextMenuListener.java b/core/tests/coretests/src/android/widget/expandablelistview/PositionTesterContextMenuListener.java
new file mode 100644
index 0000000..b96bca1
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/expandablelistview/PositionTesterContextMenuListener.java
@@ -0,0 +1,43 @@
+package android.widget.expandablelistview;
+
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnCreateContextMenuListener;
+import android.widget.ExpandableListView;
+
+import junit.framework.Assert;
+
+public class PositionTesterContextMenuListener implements OnCreateContextMenuListener {
+
+ private int groupPosition, childPosition;
+
+ private int testType; // as returned by getPackedPositionType
+
+ public void expectGroupContextMenu(int groupPosition) {
+ this.groupPosition = groupPosition;
+ testType = ExpandableListView.PACKED_POSITION_TYPE_GROUP;
+ }
+
+ public void expectChildContextMenu(int groupPosition, int childPosition) {
+ this.groupPosition = groupPosition;
+ this.childPosition = childPosition;
+ testType = ExpandableListView.PACKED_POSITION_TYPE_CHILD;
+ }
+
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+ ExpandableListView.ExpandableListContextMenuInfo elvMenuInfo = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
+ long packedPosition = elvMenuInfo.packedPosition;
+
+ int packedPositionType = ExpandableListView.getPackedPositionType(packedPosition);
+ Assert.assertEquals("Wrong packed position type", testType, packedPositionType);
+
+ int packedPositionGroup = ExpandableListView.getPackedPositionGroup(packedPosition);
+ Assert.assertEquals("Wrong group position", groupPosition, packedPositionGroup);
+
+ if (testType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
+ int packedPositionChild = ExpandableListView.getPackedPositionChild(packedPosition);
+ Assert.assertEquals("Wrong child position", childPosition, packedPositionChild);
+ }
+ }
+}
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index ab3b3d3..baed020 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -356,25 +356,19 @@
<p>There are several alternatives for iterating through an array:</p>
-<pre>public class Foo {
- int mSplat;
-}
-public class ArrayBenchmark {
- Foo[] mArray = new Foo[27];
- {
- for (int i = 0; i < mArray.length; ++i) {
- mArray[i] = new Foo();
- }
+<pre> static class Foo {
+ int mSplat;
}
+ Foo[] mArray = ...
- public static void zero() {
+ public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
- public static void one() {
+ public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
@@ -384,13 +378,13 @@
}
}
- public static void two() {
+ public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
-}</pre>
+</pre>
<p><strong>zero()</strong> is slowest, because the JIT can't yet optimize away
the cost of getting the array length once for every iteration through the
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index e328f33..9df2695 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -187,16 +187,23 @@
// Vertical angle of view in degrees.
// Example value: "42.5". Read only.
static const char KEY_VERTICAL_VIEW_ANGLE[];
- // Exposure compensation. The value is multiplied by 100. -100 means -1 EV.
- // 130 means +1.3 EV.
- // Example value: "0" or "133". Read/write.
+ // Exposure compensation index. 0 means exposure is not adjusted.
+ // Example value: "0" or "5". Read/write.
static const char KEY_EXPOSURE_COMPENSATION[];
- // Supported exposure compensation.
- // Example value: "-100,-66,-33,0,33,66,100". Read only.
- static const char KEY_SUPPORTED_EXPOSURE_COMPENSATION[];
+ // The maximum exposure compensation index (>=0).
+ // Example value: "6". Read only.
+ static const char KEY_MAX_EXPOSURE_COMPENSATION[];
+ // The minimum exposure compensation index (<=0).
+ // Example value: "-6". Read only.
+ static const char KEY_MIN_EXPOSURE_COMPENSATION[];
+ // The exposure compensation step. Exposure compensation index multiply by
+ // step eqals to EV. Ex: if exposure compensation index is 6 and step is
+ // 0.3333, EV is -2.
+ // Example value: "0.333333333" or "0.5". Read only.
+ static const char KEY_EXPOSURE_COMPENSATION_STEP[];
- // Values for white balance settings.
+ // Values for white balance settings.
static const char WHITE_BALANCE_AUTO[];
static const char WHITE_BALANCE_INCANDESCENT[];
static const char WHITE_BALANCE_FLUORESCENT[];
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index 3f253f9..eb96d20 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -52,6 +52,7 @@
* or -1 if error.
*
* Supported param name are:
+ * duration - the recording duration.
* file.format - output file format. see mediarecorder.h for details
* vid.codec - video encoder. see mediarecorder.h for details.
* aud.codec - audio encoder. see mediarecorder.h for details.
@@ -120,6 +121,16 @@
*/
Vector<audio_decoder> getAudioDecoders() const;
+ /**
+ * Returns the number of image encoding quality levels supported.
+ */
+ Vector<int> getImageEncodingQualityLevels() const;
+
+ /**
+ * Returns the maximum amount of memory in bytes we can use for decoding a JPEG file.
+ */
+ int getImageDecodingMaxMemory() const;
+
private:
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
MediaProfiles(const MediaProfiles&); // Don't call me
@@ -257,6 +268,8 @@
static VideoEncoderCap* createVideoEncoderCap(const char **atts);
static AudioEncoderCap* createAudioEncoderCap(const char **atts);
static CamcorderProfile* createCamcorderProfile(const char **atts);
+ static int getImageEncodingQualityLevel(const char **atts);
+ static int getImageDecodingMaxMemory(const char **atts);
// Customized element tag handler for parsing the xml configuration file.
static void startElementHandler(void *userData, const char *name, const char **atts);
@@ -271,6 +284,8 @@
static void createDefaultVideoDecoders(MediaProfiles *profiles);
static void createDefaultAudioDecoders(MediaProfiles *profiles);
static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
+ static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
+ static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
static VideoEncoderCap* createDefaultH263VideoEncoderCap();
static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
static AudioEncoderCap* createDefaultAmrNBEncoderCap();
@@ -295,6 +310,8 @@
Vector<AudioDecoderCap*> mAudioDecoders;
Vector<VideoDecoderCap*> mVideoDecoders;
Vector<output_format> mEncoderOutputFileFormats;
+ Vector<int> mImageEncodingQualityLevels;
+ int mImageDecodingMaxMemory;
};
}; // namespace android
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index 1bf1759..8439e2b 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -60,7 +60,9 @@
const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
-const char CameraParameters::KEY_SUPPORTED_EXPOSURE_COMPENSATION[] = "exposure-compensation-values";
+const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
+const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
// Values for white balance settings.
const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
diff --git a/location/java/com/android/internal/location/GpsXtraDownloader.java b/location/java/com/android/internal/location/GpsXtraDownloader.java
index 02a9f48..978bda2 100644
--- a/location/java/com/android/internal/location/GpsXtraDownloader.java
+++ b/location/java/com/android/internal/location/GpsXtraDownloader.java
@@ -32,10 +32,10 @@
import android.content.Context;
import android.net.Proxy;
+import android.net.http.AndroidHttpClient;
import android.util.Config;
import android.util.Log;
-import com.android.common.AndroidHttpClient;
/**
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index e1e09b9..09aec2e 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -72,10 +72,8 @@
Log.w(mTag, "Notification sound delayed by " + delay + "msecs");
}
}
- catch (IOException e) {
+ catch (Exception e) {
Log.w(mTag, "error loading sound for " + cmd.uri, e);
- } catch (IllegalStateException e) {
- Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);
}
}
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index ce56443..eade680 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -38,6 +38,7 @@
*/
public class CamcorderProfile
{
+ private final int mDuration; // Recording duration in seconds
/**
* The Quality class represents the quality level of each CamcorderProfile.
@@ -56,6 +57,14 @@
};
/**
+ * Returns the recording duration in seconds for LOW quality CamcorderProfile
+ * used by the MMS application.
+ */
+ public static final int getMmsRecordingDurationInSeconds() {
+ return get(Quality.LOW).mDuration;
+ }
+
+ /**
* The quality level of the camcorder profile
* @see android.media.CamcorderProfile.Quality
*/
@@ -129,7 +138,8 @@
}
// Private constructor called by JNI
- private CamcorderProfile(int quality,
+ private CamcorderProfile(int duration,
+ int quality,
int fileFormat,
int videoCodec,
int videoBitRate,
@@ -141,6 +151,7 @@
int audioSampleRate,
int audioChannels) {
+ mDuration = duration;
mQuality = Quality.values()[quality];
mFileFormat = fileFormat;
mVideoCodec = videoCodec;
diff --git a/media/java/android/media/CameraProfile.java b/media/java/android/media/CameraProfile.java
new file mode 100644
index 0000000..9685e7e
--- /dev/null
+++ b/media/java/android/media/CameraProfile.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * The CameraProfile class is used to retrieve the pre-defined still image
+ * capture (jpeg) quality levels (0-100) used for low, medium, and high
+ * quality settings in the Camera application.
+ *
+ * {@hide}
+ */
+public class CameraProfile
+{
+ /**
+ * Returns a list of the pre-defined still image capture (jpeg) quality levels
+ * used for low, medium and high quality settings in the Camera application.
+ */
+ public static int[] getImageEncodingQualityLevels() {
+ int nLevels = native_get_num_image_encoding_quality_levels();
+ if (nLevels == 0) return null;
+
+ int[] levels = new int[nLevels];
+ for (int i = 0; i < nLevels; ++i) {
+ levels[i] = native_get_image_encoding_quality_level(i);
+ }
+ return levels;
+ }
+
+ static {
+ System.loadLibrary("media_jni");
+ native_init();
+ }
+
+ // Methods implemented by JNI
+ private static native final void native_init();
+ private static native final int native_get_num_image_encoding_quality_levels();
+ private static native final int native_get_image_encoding_quality_level(int index);
+}
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 19132c5..7d7533a 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -171,6 +171,7 @@
}
camcorder_quality q = static_cast<camcorder_quality>(quality);
+ int duration = sProfiles->getCamcorderProfileParamByName("duration", q);
int fileFormat = sProfiles->getCamcorderProfileParamByName("file.format", q);
int videoCodec = sProfiles->getCamcorderProfileParamByName("vid.codec", q);
int videoBitRate = sProfiles->getCamcorderProfileParamByName("vid.bps", q);
@@ -183,7 +184,7 @@
int audioChannels = sProfiles->getCamcorderProfileParamByName("aud.ch", q);
// Check on the values retrieved
- if (fileFormat == -1 || videoCodec == -1 || audioCodec == -1 ||
+ if (duration == -1 || fileFormat == -1 || videoCodec == -1 || audioCodec == -1 ||
videoBitRate == -1 || videoFrameRate == -1 || videoFrameWidth == -1 || videoFrameHeight == -1 ||
audioBitRate == -1 || audioSampleRate == -1 || audioChannels == -1) {
@@ -192,9 +193,10 @@
}
jclass camcorderProfileClazz = env->FindClass("android/media/CamcorderProfile");
- jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIII)V");
+ jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIIII)V");
return env->NewObject(camcorderProfileClazz,
camcorderProfileConstructorMethodID,
+ duration,
quality,
fileFormat,
videoCodec,
@@ -250,6 +252,25 @@
return static_cast<jint>(decoders[index]);
}
+static jint
+android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz)
+{
+ LOGV("native_get_num_image_encoding_quality_levels");
+ return sProfiles->getImageEncodingQualityLevels().size();
+}
+
+static jint
+android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint index)
+{
+ LOGV("native_get_image_encoding_quality_level");
+ Vector<int> levels = sProfiles->getImageEncodingQualityLevels();
+ if (index < 0 || index >= levels.size()) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+ return -1;
+ }
+ return static_cast<jint>(levels[index]);
+}
+
static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
{"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
{"native_get_num_file_formats", "()I", (void *)android_media_MediaProfiles_native_get_num_file_formats},
@@ -278,9 +299,17 @@
{"native_get_audio_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_audio_decoder_type},
};
+static JNINativeMethod gMethodsForCameraProfileClass[] = {
+ {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
+ {"native_get_num_image_encoding_quality_levels",
+ "()I", (void *)android_media_MediaProfiles_native_get_num_image_encoding_quality_levels},
+ {"native_get_image_encoding_quality_level","(I)I", (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level},
+};
+
static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
+static const char* const kCameraProfileClassPathName = "android/media/CameraProfile";
// This function only registers the native methods, and is called from
// JNI_OnLoad in android_media_MediaPlayer.cpp
@@ -301,6 +330,11 @@
gMethodsForDecoderCapabilitiesClass,
NELEM(gMethodsForDecoderCapabilitiesClass));
- // Success if ret1 == 0 && ret2 == 0 && ret3 == 0
- return (ret1 || ret2 || ret3);
+ int ret4 = AndroidRuntime::registerNativeMethods(env,
+ kCameraProfileClassPathName,
+ gMethodsForCameraProfileClass,
+ NELEM(gMethodsForCameraProfileClass));
+
+ // Success if all return values from above are 0
+ return (ret1 || ret2 || ret3 || ret4);
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 0efade1..1263373 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -293,6 +293,13 @@
return profile;
}
+/*static*/ int
+MediaProfiles::getImageEncodingQualityLevel(const char** atts)
+{
+ CHECK(!strcmp("quality", atts[0]));
+ return atoi(atts[1]);
+}
+
/*static*/ void
MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
{
@@ -317,6 +324,8 @@
profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
} else if (strcmp("EncoderProfile", name) == 0) {
profiles->mCamcorderProfiles.add(createCamcorderProfile(atts));
+ } else if (strcmp("ImageEncoding", name) == 0) {
+ profiles->mImageEncodingQualityLevels.add(getImageEncodingQualityLevel(atts));
}
}
@@ -446,6 +455,14 @@
AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1);
}
+/*static*/ void
+MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles)
+{
+ profiles->mImageEncodingQualityLevels.add(70);
+ profiles->mImageEncodingQualityLevels.add(80);
+ profiles->mImageEncodingQualityLevels.add(90);
+}
+
/*static*/ MediaProfiles*
MediaProfiles::createDefaultInstance()
{
@@ -456,6 +473,7 @@
createDefaultVideoDecoders(profiles);
createDefaultAudioDecoders(profiles);
createDefaultEncoderOutputFileFormats(profiles);
+ createDefaultImageEncodingQualityLevels(profiles);
sIsInitialized = true;
return profiles;
}
@@ -627,6 +645,7 @@
return -1;
}
+ if (!strcmp("duration", name)) return mCamcorderProfiles[index]->mDuration;
if (!strcmp("file.format", name)) return mCamcorderProfiles[index]->mFileFormat;
if (!strcmp("vid.codec", name)) return mCamcorderProfiles[index]->mVideoCodec->mCodec;
if (!strcmp("vid.width", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameWidth;
@@ -642,6 +661,11 @@
return -1;
}
+Vector<int> MediaProfiles::getImageEncodingQualityLevels() const
+{
+ return mImageEncodingQualityLevels; // copy out
+}
+
MediaProfiles::~MediaProfiles()
{
CHECK("destructor should never be called" == 0);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 50dad33..c26d682 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -430,6 +430,8 @@
snprintf(buffer, SIZE, " Allocation count %i\n", count);
result.append(buffer);
+ snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
+ result.append(buffer);
AllocEntry * entries = new AllocEntry[count];
@@ -478,7 +480,7 @@
for (size_t i = 0; i < count; i++) {
AllocEntry *e = &entries[i];
- snprintf(buffer, SIZE, "size %8i, dup %4i", e->size, e->dups);
+ snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
result.append(buffer);
for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
if (ct) {
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 165ac09..f1c3f0f 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -439,14 +439,16 @@
printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
char buffer[256];
- if (chunk_size <= sizeof(buffer)) {
- if (mDataSource->readAt(*offset, buffer, chunk_size)
- < (ssize_t)chunk_size) {
- return ERROR_IO;
- }
-
- hexdump(buffer, chunk_size);
+ size_t n = chunk_size;
+ if (n > sizeof(buffer)) {
+ n = sizeof(buffer);
}
+ if (mDataSource->readAt(*offset, buffer, n)
+ < (ssize_t)n) {
+ return ERROR_IO;
+ }
+
+ hexdump(buffer, n);
#endif
PathAdder autoAdder(&mPath, chunk_type);
@@ -981,7 +983,13 @@
if (U32_AT(buffer) != 0) {
// Should be version 0, flags 0.
- return ERROR_MALFORMED;
+
+ // If it's not, let's assume this is one of those
+ // apparently malformed chunks that don't have flags
+ // and completely different semantics than what's
+ // in the MPEG4 specs and skip it.
+ *offset += chunk_size;
+ return OK;
}
off_t stop_offset = *offset + chunk_size;
@@ -1626,7 +1634,8 @@
if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
|| !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
- || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)) {
+ || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
+ || !memcmp(header, "ftypkddi", 8)) {
*mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
*confidence = 0.1;
diff --git a/mms-common/Android.mk b/mms-common/Android.mk
index de994c0..57f1ccc 100644
--- a/mms-common/Android.mk
+++ b/mms-common/Android.mk
@@ -20,6 +20,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := mms-common
LOCAL_SRC_FILES := $(call all-java-files-under, java)
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
include $(BUILD_STATIC_JAVA_LIBRARY)
# Include this library in the build server's output directory
diff --git a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
index 0237bc2..87e4758 100644
--- a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
+++ b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
@@ -32,8 +32,8 @@
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
+import android.util.Patterns;
-import com.android.common.Patterns;
import android.database.sqlite.SqliteWrapper;
/**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 8036e52..18e247e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -44,8 +44,8 @@
import android.util.Config;
import android.util.Log;
import android.util.Xml;
-import com.android.common.XmlUtils;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
diff --git a/preloaded-classes b/preloaded-classes
index aaae440..9fc000f 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -308,10 +308,12 @@
android.net.Uri$OpaqueUri
android.net.Uri$Part
android.net.WebAddress
+android.net.http.AndroidHttpClient
android.net.http.AndroidHttpClientConnection
android.net.http.EventHandler
android.net.http.Headers
android.net.http.HttpsConnection
+android.net.http.HttpDateTime
android.net.http.Request
android.net.http.RequestQueue
android.net.http.SslCertificate
@@ -473,6 +475,7 @@
android.util.Log
android.util.LongSparseArray
android.util.MonthDisplayHelper
+android.util.Patterns
android.util.SparseArray
android.util.StateSet
android.util.TypedValue
@@ -618,13 +621,6 @@
android.widget.ZoomButton
android.widget.ZoomButtonsController
android.widget.ZoomControls
-com.android.common.AndroidHttpClient
-com.android.common.DomainNameValidator
-com.android.common.FastXmlSerializer
-com.android.common.HttpDateTime
-com.android.common.Patterns
-com.android.common.Rfc822Validator
-com.android.common.userhappiness.UserHappinessSignals
com.android.internal.R$styleable
com.android.internal.app.AlertActivity
com.android.internal.app.AlertController
@@ -652,6 +648,7 @@
com.android.internal.os.ZygoteConnection
com.android.internal.os.ZygoteConnection$Arguments
com.android.internal.os.ZygoteInit
+com.android.internal.net.DomainNameValidator
com.android.internal.policy.PolicyManager
com.android.internal.policy.impl.PhoneLayoutInflater
com.android.internal.policy.impl.PhoneWindow
@@ -672,7 +669,9 @@
com.android.internal.telephony.gsm.SmsMessage$PduParser
com.android.internal.util.ArrayUtils
com.android.internal.util.FastMath
+com.android.internal.util.FastXmlSerializer
com.android.internal.util.HanziToPinyin
+com.android.internal.util.XmlUtils
com.android.internal.view.IInputConnectionWrapper
com.android.internal.view.IInputContext$Stub
com.android.internal.view.IInputMethodManager$Stub
diff --git a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
index bee3938..e8cf2f7 100644
--- a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
+++ b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
@@ -29,7 +29,7 @@
import android.text.format.Time;
import android.util.Log;
import android.util.Xml;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 0b466f1..a5b0db9 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -57,7 +57,7 @@
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.appwidget.IAppWidgetHost;
-import com.android.common.FastXmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index d4b28e2..27faf3dc5 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -374,7 +374,7 @@
mProvisioned = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.BACKUP_PROVISIONED, 0) != 0;
mAutoRestore = Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.BACKUP_AUTO_RESTORE, 0) != 0;
+ Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
// If Encrypted file systems is enabled or disabled, this call will return the
// correct directory.
mBaseStateDir = new File(Environment.getSecureDataDirectory(), "backup");
@@ -2289,7 +2289,7 @@
if (DEBUG) Log.v(TAG, "restoreAtInstall pkg=" + packageName
+ " token=" + Integer.toHexString(token));
- if (restoreSet != 0) {
+ if (mAutoRestore && mProvisioned && restoreSet != 0) {
// okay, we're going to attempt a restore of this package from this restore set.
// The eventual message back into the Package Manager to run the post-install
// steps for 'token' will be issued from the restore handling code.
@@ -2306,8 +2306,8 @@
restoreSet, pkg, token);
mBackupHandler.sendMessage(msg);
} else {
- // No way to attempt a restore; just tell the Package Manager to proceed
- // with the post-install handling for this package.
+ // Auto-restore disabled or no way to attempt a restore; just tell the Package
+ // Manager to proceed with the post-install handling for this package.
if (DEBUG) Log.v(TAG, "No restore set -- skipping restore");
try {
mPackageManagerBinder.finishPackageInstall(token);
@@ -2484,6 +2484,7 @@
pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
+ " / " + (!mProvisioned ? "not " : "") + "provisioned / "
+ (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
+ pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
pw.println("Last backup pass: " + mLastBackupPass
+ " (now = " + System.currentTimeMillis() + ')');
pw.println(" next scheduled: " + mNextBackupPass);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index df685ab..19f4b8a 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -934,9 +934,18 @@
int newType = -1;
int newPriority = -1;
+ boolean noMobileData = !getMobileDataEnabled();
for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
if (checkType == prevNetType) continue;
if (mNetAttributes[checkType] == null) continue;
+ if (mNetAttributes[checkType].mRadio == ConnectivityManager.TYPE_MOBILE &&
+ noMobileData) {
+ if (DBG) {
+ Log.d(TAG, "not failing over to mobile type " + checkType +
+ " because Mobile Data Disabled");
+ }
+ continue;
+ }
if (mNetAttributes[checkType].isDefault()) {
/* TODO - if we have multiple nets we could use
* we may want to put more thought into which we choose
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index ac65aa9..9899e99 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -16,9 +16,9 @@
package com.android.server;
-import com.android.common.FastXmlSerializer;
-import com.android.common.XmlUtils;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
import org.xmlpull.v1.XmlPullParser;
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 027f35c..a0c850f 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -305,6 +305,14 @@
(KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE);
mKeyguardLock = keyguardManager.newKeyguardLock(TAG);
+ final boolean enableCarMode = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
+ if (enableCarMode) {
+ try {
+ setCarMode(enableCarMode);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to change car mode.", e);
+ }
+ }
// don't bother broadcasting undocked here
if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
update();
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index 2640cfb..1bb897b 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -32,7 +32,7 @@
import android.view.Surface;
import android.view.WindowManagerPolicy;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index a23fac4..63fdaef 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -18,9 +18,9 @@
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
-import com.android.common.FastXmlSerializer;
-import com.android.common.XmlUtils;
import com.android.internal.content.PackageHelper;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
import com.android.server.JournaledFile;
import org.xmlpull.v1.XmlPullParser;
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 481e6a4..aebb0ff 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -67,9 +67,9 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.service.wallpaper.ImageWallpaper;
+import com.android.internal.util.FastXmlSerializer;
import com.android.server.DevicePolicyManagerService.ActiveAdmin;
import com.android.server.DevicePolicyManagerService.MyPackageMonitor;
-import com.android.common.FastXmlSerializer;
class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperService";
diff --git a/telephony/java/com/android/internal/telephony/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java
index 4232887..fa91457 100644
--- a/telephony/java/com/android/internal/telephony/IccProvider.java
+++ b/telephony/java/com/android/internal/telephony/IccProvider.java
@@ -19,8 +19,9 @@
import android.content.ContentProvider;
import android.content.UriMatcher;
import android.content.ContentValues;
-import com.android.common.ArrayListCursor;
+import android.database.AbstractCursor;
import android.database.Cursor;
+import android.database.CursorWindow;
import android.net.Uri;
import android.os.SystemProperties;
import android.os.RemoteException;
@@ -35,6 +36,149 @@
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.IIccPhoneBook;
+/**
+ * XXX old code -- should be replaced with MatrixCursor.
+ * @deprecated This is has been replaced by MatrixCursor.
+*/
+class ArrayListCursor extends AbstractCursor {
+ private String[] mColumnNames;
+ private ArrayList<Object>[] mRows;
+
+ @SuppressWarnings({"unchecked"})
+ public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
+ int colCount = columnNames.length;
+ boolean foundID = false;
+ // Add an _id column if not in columnNames
+ for (int i = 0; i < colCount; ++i) {
+ if (columnNames[i].compareToIgnoreCase("_id") == 0) {
+ mColumnNames = columnNames;
+ foundID = true;
+ break;
+ }
+ }
+
+ if (!foundID) {
+ mColumnNames = new String[colCount + 1];
+ System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
+ mColumnNames[colCount] = "_id";
+ }
+
+ int rowCount = rows.size();
+ mRows = new ArrayList[rowCount];
+
+ for (int i = 0; i < rowCount; ++i) {
+ mRows[i] = rows.get(i);
+ if (!foundID) {
+ mRows[i].add(i);
+ }
+ }
+ }
+
+ @Override
+ public void fillWindow(int position, CursorWindow window) {
+ if (position < 0 || position > getCount()) {
+ return;
+ }
+
+ window.acquireReference();
+ try {
+ int oldpos = mPos;
+ mPos = position - 1;
+ window.clear();
+ window.setStartPosition(position);
+ int columnNum = getColumnCount();
+ window.setNumColumns(columnNum);
+ while (moveToNext() && window.allocRow()) {
+ for (int i = 0; i < columnNum; i++) {
+ final Object data = mRows[mPos].get(i);
+ if (data != null) {
+ if (data instanceof byte[]) {
+ byte[] field = (byte[]) data;
+ if (!window.putBlob(field, mPos, i)) {
+ window.freeLastRow();
+ break;
+ }
+ } else {
+ String field = data.toString();
+ if (!window.putString(field, mPos, i)) {
+ window.freeLastRow();
+ break;
+ }
+ }
+ } else {
+ if (!window.putNull(mPos, i)) {
+ window.freeLastRow();
+ break;
+ }
+ }
+ }
+ }
+
+ mPos = oldpos;
+ } catch (IllegalStateException e){
+ // simply ignore it
+ } finally {
+ window.releaseReference();
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return mRows.length;
+ }
+
+ @Override
+ public String[] getColumnNames() {
+ return mColumnNames;
+ }
+
+ @Override
+ public byte[] getBlob(int columnIndex) {
+ return (byte[]) mRows[mPos].get(columnIndex);
+ }
+
+ @Override
+ public String getString(int columnIndex) {
+ Object cell = mRows[mPos].get(columnIndex);
+ return (cell == null) ? null : cell.toString();
+ }
+
+ @Override
+ public short getShort(int columnIndex) {
+ Number num = (Number) mRows[mPos].get(columnIndex);
+ return num.shortValue();
+ }
+
+ @Override
+ public int getInt(int columnIndex) {
+ Number num = (Number) mRows[mPos].get(columnIndex);
+ return num.intValue();
+ }
+
+ @Override
+ public long getLong(int columnIndex) {
+ Number num = (Number) mRows[mPos].get(columnIndex);
+ return num.longValue();
+ }
+
+ @Override
+ public float getFloat(int columnIndex) {
+ Number num = (Number) mRows[mPos].get(columnIndex);
+ return num.floatValue();
+ }
+
+ @Override
+ public double getDouble(int columnIndex) {
+ Number num = (Number) mRows[mPos].get(columnIndex);
+ return num.doubleValue();
+ }
+
+ @Override
+ public boolean isNull(int columnIndex) {
+ return mRows[mPos].get(columnIndex) == null;
+ }
+}
+
/**
* {@hide}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
index 0e186d0..37c1d55 100644
--- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
@@ -23,8 +23,8 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
+import com.android.internal.util.XmlUtils;
-import com.android.common.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 905d5e3..d893ec4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -18,8 +18,8 @@
import android.os.Message;
import android.util.Log;
+import android.util.Patterns;
-import com.android.common.Patterns;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
index abb0230..9ea30101 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
@@ -13,7 +13,7 @@
import android.util.Log;
import android.util.Xml;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
public class SpnOverride {
private HashMap<String, String> CarrierSpnMap;
diff --git a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
index 0bedd53..0e49e35 100644
--- a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
@@ -28,7 +28,8 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import com.android.common.XmlUtils;
+
+import com.android.internal.util.XmlUtils;
/**
* {@hide}
diff --git a/common/tests/res/raw/alt_ip_only.crt b/tests/AndroidTests/res/raw/alt_ip_only.crt
similarity index 100%
rename from common/tests/res/raw/alt_ip_only.crt
rename to tests/AndroidTests/res/raw/alt_ip_only.crt
diff --git a/common/tests/res/raw/subject_alt_only.crt b/tests/AndroidTests/res/raw/subject_alt_only.crt
similarity index 100%
rename from common/tests/res/raw/subject_alt_only.crt
rename to tests/AndroidTests/res/raw/subject_alt_only.crt
diff --git a/common/tests/res/raw/subject_only.crt b/tests/AndroidTests/res/raw/subject_only.crt
similarity index 100%
rename from common/tests/res/raw/subject_only.crt
rename to tests/AndroidTests/res/raw/subject_only.crt
diff --git a/common/tests/res/raw/subject_with_alt_names.crt b/tests/AndroidTests/res/raw/subject_with_alt_names.crt
similarity index 100%
rename from common/tests/res/raw/subject_with_alt_names.crt
rename to tests/AndroidTests/res/raw/subject_with_alt_names.crt
diff --git a/common/tests/res/raw/subject_with_wild_alt_name.crt b/tests/AndroidTests/res/raw/subject_with_wild_alt_name.crt
similarity index 100%
rename from common/tests/res/raw/subject_with_wild_alt_name.crt
rename to tests/AndroidTests/res/raw/subject_with_wild_alt_name.crt
diff --git a/common/tests/res/raw/wild_alt_name_only.crt b/tests/AndroidTests/res/raw/wild_alt_name_only.crt
similarity index 100%
rename from common/tests/res/raw/wild_alt_name_only.crt
rename to tests/AndroidTests/res/raw/wild_alt_name_only.crt
diff --git a/common/tests/src/com/android/common/DNParserTest.java b/tests/AndroidTests/src/com/android/unit_tests/DNParserTest.java
similarity index 95%
rename from common/tests/src/com/android/common/DNParserTest.java
rename to tests/AndroidTests/src/com/android/unit_tests/DNParserTest.java
index 34b140a..61d0b42 100644
--- a/common/tests/src/com/android/common/DNParserTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DNParserTest.java
@@ -13,7 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.common;
+package com.android.unit_tests;
+
+import com.android.internal.net.DNParser;
import javax.security.auth.x500.X500Principal;
diff --git a/common/tests/src/com/android/common/DomainNameValidatorTest.java b/tests/AndroidTests/src/com/android/unit_tests/DomainNameValidatorTest.java
similarity index 98%
rename from common/tests/src/com/android/common/DomainNameValidatorTest.java
rename to tests/AndroidTests/src/com/android/unit_tests/DomainNameValidatorTest.java
index b825be4..1754dbe 100644
--- a/common/tests/src/com/android/common/DomainNameValidatorTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DomainNameValidatorTest.java
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.common;
+package com.android.unit_tests;
-import com.android.common.tests.R;
+import com.android.internal.net.DomainNameValidator;
import android.test.AndroidTestCase;
diff --git a/common/tests/src/com/android/common/PatternsTest.java b/tests/AndroidTests/src/com/android/unit_tests/PatternsTest.java
similarity index 97%
rename from common/tests/src/com/android/common/PatternsTest.java
rename to tests/AndroidTests/src/com/android/unit_tests/PatternsTest.java
index 9e2ad58..0edcd6d 100644
--- a/common/tests/src/com/android/common/PatternsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PatternsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package com.android.common;
+package com.android.unit_tests;
import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
+import android.util.Patterns;
import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+
+import junit.framework.TestCase;
public class PatternsTest extends TestCase {
diff --git a/tests/SslLoad/src/com/android/sslload/SslLoad.java b/tests/SslLoad/src/com/android/sslload/SslLoad.java
index 1470d48..62aa524 100644
--- a/tests/SslLoad/src/com/android/sslload/SslLoad.java
+++ b/tests/SslLoad/src/com/android/sslload/SslLoad.java
@@ -35,7 +35,7 @@
import android.widget.Button;
import android.widget.TextView;
import android.util.Log;
-import com.android.common.AndroidHttpClient;
+import android.net.http.AndroidHttpClient;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 41d9f9d..8e9e75f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,7 +16,7 @@
package com.android.layoutlib.bridge;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import com.android.layoutlib.api.ILayoutBridge;
import com.android.layoutlib.api.ILayoutLog;
import com.android.layoutlib.api.ILayoutResult;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
index 6a98780..70c5bd7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
@@ -16,7 +16,7 @@
package com.android.layoutlib.bridge;
-import com.android.common.XmlUtils;
+import com.android.internal.util.XmlUtils;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;