Merge change I129483f8 into eclair-mr2
* changes:
Optional use of UTF-8 strings in resource bundles
diff --git a/api/current.xml b/api/current.xml
index 41714ef..a5d1967 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -23672,6 +23672,17 @@
</implements>
<implements name="android.content.DialogInterface.OnDismissListener">
</implements>
+<method name="getSearchablesInGlobalSearch"
+ return="java.util.List<android.app.SearchableInfo>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="onCancel"
return="void"
abstract="false"
@@ -24131,6 +24142,444 @@
>
</method>
</interface>
+<class name="SearchableInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="autoUrlDetect"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="findActionKey"
+ return="android.app.SearchableInfo.ActionKeyInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
+<method name="getHintId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getIconId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getImeOptions"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getInputType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getLabelId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSearchActivity"
+ return="android.content.ComponentName"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSearchButtonText"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSettingsDescription"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestAuthority"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestIntentAction"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestIntentData"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestPackage"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestPath"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestSelection"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestThreshold"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceLanguageId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceLanguageModeId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceMaxResults"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoicePromptTextId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchLaunchRecognizer"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchLaunchWebSearch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="queryAfterZeroResults"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldIncludeInGlobalSearch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldRewriteQueryFromData"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldRewriteQueryFromText"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="SearchableInfo.ActionKeyInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getKeyCode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getQueryActionMsg"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestActionMsg"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestActionMsgColumn"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</class>
<class name="Service"
extends="android.content.ContextWrapper"
abstract="true"
@@ -83994,6 +84443,148 @@
>
</method>
</class>
+<class name="TrafficStats"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="TrafficStats"
+ type="android.net.TrafficStats"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getMobileRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileRxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileTxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalRxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalTxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUidRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uid" type="int">
+</parameter>
+</method>
+<method name="getUidTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uid" type="int">
+</parameter>
+</method>
+<field name="UNSUPPORTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="Uri"
extends="java.lang.Object"
abstract="true"
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ab5e102..1f17476 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -2038,10 +2038,8 @@
* Returns a list of the searchable activities that can be included in global search.
*
* @return a list containing searchable information for all searchable activities
- * that have the <code>exported</code> attribute set in their searchable
- * meta-data.
- *
- * @hide because SearchableInfo is not part of the API.
+ * that have the <code>android:includeInGlobalSearch</code> attribute set
+ * in their searchable meta-data.
*/
public List<SearchableInfo> getSearchablesInGlobalSearch() {
try {
diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java
index cbf7b3d..9897742 100644
--- a/core/java/android/app/SearchableInfo.java
+++ b/core/java/android/app/SearchableInfo.java
@@ -38,8 +38,9 @@
import java.util.HashMap;
/**
- *
- * @hide Pending API council approval
+ * Searchability meta-data for an activity.
+ * See <a href="SearchManager.html#SearchabilityMetadata">Searchability meta-data</a>
+ * for more information.
*/
public final class SearchableInfo implements Parcelable {
@@ -87,9 +88,9 @@
private final String mSuggestProviderPackage;
// Flag values for Searchable_voiceSearchMode
- private static int VOICE_SEARCH_SHOW_BUTTON = 1;
- private static int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
- private static int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
+ private static final int VOICE_SEARCH_SHOW_BUTTON = 1;
+ private static final int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
+ private static final int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
private final int mVoiceSearchMode;
private final int mVoiceLanguageModeId; // voiceLanguageModel
private final int mVoicePromptTextId; // voicePromptText
@@ -123,6 +124,8 @@
/**
* Checks whether the badge should be a text label.
+ *
+ * @hide This feature is deprecated, no need to add it to the API.
*/
public boolean useBadgeLabel() {
return 0 != (mSearchMode & SEARCH_MODE_BADGE_LABEL);
@@ -130,6 +133,8 @@
/**
* Checks whether the badge should be an icon.
+ *
+ * @hide This feature is deprecated, no need to add it to the API.
*/
public boolean useBadgeIcon() {
return (0 != (mSearchMode & SEARCH_MODE_BADGE_ICON)) && (mIconId != 0);
@@ -220,6 +225,7 @@
*
* @param context You need to supply a context to start with
* @return Returns a context related to the searchable activity
+ * @hide
*/
public Context getActivityContext(Context context) {
return createActivityContext(context, mSearchActivity);
@@ -251,6 +257,7 @@
* @param activityContext If we can determine that the provider and the activity are the
* same, we'll just return this one.
* @return Returns a context related to the context provider
+ * @hide
*/
public Context getProviderContext(Context context, Context activityContext) {
Context theirContext = null;
@@ -351,7 +358,11 @@
}
/**
- * Private class used to hold the "action key" configuration
+ * Information about an action key in searchability meta-data.
+ * See <a href="SearchManager.html#SearchabilityMetadata">Searchability meta-data</a>
+ * for more information.
+ *
+ * @see SearchableInfo#findActionKey(int)
*/
public static class ActionKeyInfo implements Parcelable {
@@ -368,7 +379,7 @@
* construct the object.
* @throws IllegalArgumentException if the action key configuration is invalid
*/
- public ActionKeyInfo(Context activityContext, AttributeSet attr) {
+ ActionKeyInfo(Context activityContext, AttributeSet attr) {
TypedArray a = activityContext.obtainStyledAttributes(attr,
com.android.internal.R.styleable.SearchableActionKey);
@@ -399,7 +410,7 @@
* @param in The Parcel containing the previously written ActionKeyInfo,
* positioned at the location in the buffer where it was written.
*/
- public ActionKeyInfo(Parcel in) {
+ private ActionKeyInfo(Parcel in) {
mKeyCode = in.readInt();
mQueryActionMsg = in.readString();
mSuggestActionMsg = in.readString();
@@ -461,6 +472,8 @@
* @param activityInfo Activity to get search information from.
* @return Search information about the given activity, or {@code null} if
* the activity has no or invalid searchability meta-data.
+ *
+ * @hide For use by SearchManagerService.
*/
public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
// for each component, try to find metadata
@@ -720,7 +733,7 @@
* @param in The Parcel containing the previously written SearchableInfo,
* positioned at the location in the buffer where it was written.
*/
- public SearchableInfo(Parcel in) {
+ SearchableInfo(Parcel in) {
mLabelId = in.readInt();
mSearchActivity = ComponentName.readFromParcel(in);
mHintId = in.readInt();
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 30e1712..c4e1877 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -287,6 +287,14 @@
* {@link #onStart} and returns either {@link #START_STICKY}
* or {@link #START_STICKY_COMPATIBILITY}.
*
+ * <p>If you need your application to run on platform versions prior to API
+ * level 5, you can use the following model to handle the older {@link #onStart}
+ * callback in that case. The <code>handleCommand</code> method is implemented by
+ * you as appropriate:
+ *
+ * <pre>{@include development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+ * start_compatibility}</pre>
+ *
* @param intent The Intent supplied to {@link android.content.Context#startService},
* as given. This may be null if the service is being restarted after
* its process has gone away, and it had previously returned anything
@@ -462,6 +470,13 @@
* if your service is performing background music playback, so the user
* would notice if their music stopped playing.
*
+ * <p>If you need your application to run on platform versions prior to API
+ * level 5, you can use the following model to call the the older {@link #setForeground}
+ * or this modern method as appropriate:
+ *
+ * <pre>{@include development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+ * foreground_compatibility}</pre>
+ *
* @param id The identifier for this notification as per
* {@link NotificationManager#notify(int, Notification)
* NotificationManager.notify(int, Notification)}.
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 7df3637..fda9b81 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -199,6 +199,22 @@
}
}
+ /** Check if any A2DP sink is in Non Disconnected state
+ * i.e playing, connected, connecting, disconnecting.
+ * @return a unmodifiable set of connected A2DP sinks, or null on error.
+ * @hide
+ */
+ public Set<BluetoothDevice> getNonDisconnectedSinks() {
+ if (DBG) log("getNonDisconnectedSinks()");
+ try {
+ return Collections.unmodifiableSet(
+ new HashSet<BluetoothDevice>(Arrays.asList(mService.getNonDisconnectedSinks())));
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return null;
+ }
+ }
+
/** Get the state of an A2DP sink
* @param device Remote BT device.
* @return State code, one of STATE_
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 002cf4e..168fe3b 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -29,6 +29,7 @@
boolean suspendSink(in BluetoothDevice device);
boolean resumeSink(in BluetoothDevice device);
BluetoothDevice[] getConnectedSinks(); // change to Set<> once AIDL supports
+ BluetoothDevice[] getNonDisconnectedSinks(); // change to Set<> once AIDL supports
int getSinkState(in BluetoothDevice device);
boolean setSinkPriority(in BluetoothDevice device, int priority);
int getSinkPriority(in BluetoothDevice device);
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 0db6155..091d44e 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -17,10 +17,10 @@
package android.content;
import android.accounts.Account;
+import android.net.TrafficStats;
import android.os.Bundle;
-import android.os.Process;
-import android.os.NetStat;
import android.os.IBinder;
+import android.os.Process;
import android.os.RemoteException;
import android.util.EventLog;
@@ -157,8 +157,8 @@
SyncResult syncResult = new SyncResult();
int uid = Process.myUid();
- mInitialTxBytes = NetStat.getUidTxBytes(uid);
- mInitialRxBytes = NetStat.getUidRxBytes(uid);
+ mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
+ mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
ContentProviderClient provider = null;
try {
provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority);
@@ -175,8 +175,8 @@
if (!isCanceled()) {
mSyncContext.onFinished(syncResult);
}
- onLogSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
- NetStat.getUidRxBytes(uid) - mInitialRxBytes, syncResult);
+ onLogSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+ TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, syncResult);
// synchronize so that the assignment will be seen by other threads
// that also synchronize accesses to mSyncThread
synchronized (mSyncThreadLock) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d77a6ca..3344158 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1142,7 +1142,6 @@
* Use with {@link #getSystemService} to retrieve a
* {@link android.accounts.AccountManager} for receiving intents at a
* time of your choosing.
- * TODO STOPSHIP perform a final review of the the account apis before shipping
*
* @see #getSystemService
* @see android.accounts.AccountManager
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 8d69814..a96e896 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -540,10 +540,33 @@
* {@link #putExtra}.
*
* <ul>
- * <li> {@link #EXTRA_TEMPLATE}
+ * <li> {@link #EXTRA_ALARM_COUNT}
+ * <li> {@link #EXTRA_BCC}
+ * <li> {@link #EXTRA_CC}
+ * <li> {@link #EXTRA_CHANGED_COMPONENT_NAME}
+ * <li> {@link #EXTRA_DATA_REMOVED}
+ * <li> {@link #EXTRA_DOCK_STATE}
+ * <li> {@link #EXTRA_DOCK_STATE_CAR}
+ * <li> {@link #EXTRA_DOCK_STATE_DESK}
+ * <li> {@link #EXTRA_DOCK_STATE_UNDOCKED}
+ * <li> {@link #EXTRA_DONT_KILL_APP}
+ * <li> {@link #EXTRA_EMAIL}
+ * <li> {@link #EXTRA_INITIAL_INTENTS}
* <li> {@link #EXTRA_INTENT}
+ * <li> {@link #EXTRA_KEY_EVENT}
+ * <li> {@link #EXTRA_PHONE_NUMBER}
+ * <li> {@link #EXTRA_REMOTE_INTENT_TOKEN}
+ * <li> {@link #EXTRA_REPLACING}
+ * <li> {@link #EXTRA_SHORTCUT_ICON}
+ * <li> {@link #EXTRA_SHORTCUT_ICON_RESOURCE}
+ * <li> {@link #EXTRA_SHORTCUT_INTENT}
* <li> {@link #EXTRA_STREAM}
+ * <li> {@link #EXTRA_SHORTCUT_NAME}
+ * <li> {@link #EXTRA_SUBJECT}
+ * <li> {@link #EXTRA_TEMPLATE}
* <li> {@link #EXTRA_TEXT}
+ * <li> {@link #EXTRA_TITLE}
+ * <li> {@link #EXTRA_UID}
* </ul>
*
* <h3>Flags</h3>
diff --git a/core/java/android/content/TempProviderSyncAdapter.java b/core/java/android/content/TempProviderSyncAdapter.java
index b46c545..5ccaa26 100644
--- a/core/java/android/content/TempProviderSyncAdapter.java
+++ b/core/java/android/content/TempProviderSyncAdapter.java
@@ -1,9 +1,12 @@
package android.content;
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
import android.database.SQLException;
+import android.net.TrafficStats;
import android.os.Bundle;
import android.os.Debug;
-import android.os.NetStat;
import android.os.Parcelable;
import android.os.Process;
import android.os.SystemProperties;
@@ -12,9 +15,6 @@
import android.util.EventLog;
import android.util.Log;
import android.util.TimingLogger;
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
import java.io.IOException;
@@ -203,8 +203,8 @@
if (mProviderSyncStarted) mProvider.onSyncCanceled();
// We may lose the last few sync events when canceling. Oh well.
int uid = Process.myUid();
- logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
- NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
+ logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+ TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
}
@Override
@@ -212,8 +212,8 @@
Process.setThreadPriority(Process.myTid(),
Process.THREAD_PRIORITY_BACKGROUND);
int uid = Process.myUid();
- mInitialTxBytes = NetStat.getUidTxBytes(uid);
- mInitialRxBytes = NetStat.getUidRxBytes(uid);
+ mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
+ mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
try {
sync(mSyncContext, mAccount, mAuthority, mExtras);
} catch (SQLException e) {
@@ -222,8 +222,8 @@
} finally {
mSyncThread = null;
if (!mIsCanceled) {
- logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
- NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
+ logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+ TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
mSyncContext.onFinished(mResult);
}
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index ac159f4..d90536c 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -930,8 +930,8 @@
/**
* Gets the supported preview sizes.
*
- * @return a List of Size object. null if preview size setting is not
- * supported.
+ * @return a List of Size object. This method will always return a list
+ * with at least one element.
*/
public List<Size> getSupportedPreviewSizes() {
String str = get(KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX);
@@ -1065,8 +1065,8 @@
/**
* Gets the supported preview formats.
*
- * @return a List of Integer objects. null if preview format setting is
- * not supported.
+ * @return a List of Integer objects. This method will always return a
+ * list with at least one element.
*/
public List<Integer> getSupportedPreviewFormats() {
String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
@@ -1104,8 +1104,8 @@
/**
* Gets the supported picture sizes.
*
- * @return a List of Size objects. null if picture size setting is not
- * supported.
+ * @return a List of Size objects. This method will always return a list
+ * with at least one element.
*/
public List<Size> getSupportedPictureSizes() {
String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
@@ -1143,12 +1143,18 @@
/**
* Gets the supported picture formats.
*
- * @return a List of Integer objects (values are PixelFormat.XXX). null
- * if picture setting is not supported.
+ * @return a List of Integer objects (values are PixelFormat.XXX). This
+ * method will always return a list with at least one element.
*/
public List<Integer> getSupportedPictureFormats() {
- String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
- return splitInt(str);
+ String str = get(KEY_PICTURE_FORMAT + SUPPORTED_VALUES_SUFFIX);
+ ArrayList<Integer> formats = new ArrayList<Integer>();
+ for (String s : split(str)) {
+ int f = pixelFormatForCameraFormat(s);
+ if (f == PixelFormat.UNKNOWN) continue;
+ formats.add(f);
+ }
+ return formats;
}
private String cameraFormatForPixelFormat(int pixel_format) {
@@ -1443,8 +1449,8 @@
/**
* Gets the supported focus modes.
*
- * @return a List of FOCUS_MODE_XXX string constants. null if focus mode
- * setting is not supported.
+ * @return a List of FOCUS_MODE_XXX string constants. This method will
+ * always return a list with at least one element.
*/
public List<String> getSupportedFocusModes() {
String str = get(KEY_FOCUS_MODE + SUPPORTED_VALUES_SUFFIX);
diff --git a/core/java/android/os/NetStat.java b/core/java/android/net/TrafficStats.java
similarity index 71%
rename from core/java/android/os/NetStat.java
rename to core/java/android/net/TrafficStats.java
index e294cdf..62e9f1f 100644
--- a/core/java/android/os/NetStat.java
+++ b/core/java/android/net/TrafficStats.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.os;
+package android.net;
import android.util.Log;
@@ -22,11 +22,22 @@
import java.io.RandomAccessFile;
import java.io.IOException;
-/** @hide */
-public class NetStat {
+/**
+ * Class that provides network traffic statistics. These statistics include bytes transmitted and
+ * received and network packets transmitted and received, over all interfaces, over the mobile
+ * interface, and on a per-UID basis.
+ * <p>
+ * These statistics may not be available on all platforms. If the statistics are not supported
+ * by this device, {@link #UNSUPPORTED} will be returned.
+ */
+public class TrafficStats {
+ /**
+ * The return value to indicate that the device does not support the statistic.
+ */
+ public final static int UNSUPPORTED = -1;
// Logging tag.
- private final static String TAG = "netstat";
+ private final static String TAG = "trafficstats";
// We pre-create all the File objects so we don't spend a lot of
// CPU at runtime converting from Java Strings to byte[] for the
@@ -38,36 +49,40 @@
private final static File SYS_CLASS_NET_DIR = new File("/sys/class/net");
/**
- * Get total number of tx packets sent through rmnet0 or ppp0
+ * Get the total number of packets transmitted through the mobile interface.
*
- * @return number of Tx packets through rmnet0 or ppp0
+ * @return number of packets. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getMobileTxPkts() {
return getMobileStat(MOBILE_TX_PACKETS);
}
/**
- * Get total number of rx packets received through rmnet0 or ppp0
+ * Get the total number of packets received through the mobile interface.
*
- * @return number of Rx packets through rmnet0 or ppp0
+ * @return number of packets. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getMobileRxPkts() {
return getMobileStat(MOBILE_RX_PACKETS);
}
/**
- * Get total number of tx bytes received through rmnet0 or ppp0
+ * Get the total number of bytes transmitted through the mobile interface.
*
- * @return number of Tx bytes through rmnet0 or ppp0
+ * @return number of bytes. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getMobileTxBytes() {
return getMobileStat(MOBILE_TX_BYTES);
}
/**
- * Get total number of rx bytes received through rmnet0 or ppp0
+ * Get the total number of bytes received through the mobile interface.
*
- * @return number of Rx bytes through rmnet0 or ppp0
+ * @return number of bytes. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getMobileRxBytes() {
return getMobileStat(MOBILE_RX_BYTES);
@@ -76,7 +91,8 @@
/**
* Get the total number of packets sent through all network interfaces.
*
- * @return the number of packets sent through all network interfaces
+ * @return the number of packets. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getTotalTxPkts() {
return getTotalStat("tx_packets");
@@ -85,7 +101,8 @@
/**
* Get the total number of packets received through all network interfaces.
*
- * @return the number of packets received through all network interfaces
+ * @return number of packets. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getTotalRxPkts() {
return getTotalStat("rx_packets");
@@ -94,7 +111,8 @@
/**
* Get the total number of bytes sent through all network interfaces.
*
- * @return the number of bytes sent through all network interfaces
+ * @return number of bytes. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getTotalTxBytes() {
return getTotalStat("tx_bytes");
@@ -103,35 +121,35 @@
/**
* Get the total number of bytes received through all network interfaces.
*
- * @return the number of bytes received through all network interfaces
+ * @return number of bytes. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getTotalRxBytes() {
return getTotalStat("rx_bytes");
}
/**
- * Gets network bytes sent for this UID.
+ * Get the number of bytes sent through the network for this UID.
* The statistics are across all interfaces.
- * The statistics come from /proc/uid_stat.
*
* {@see android.os.Process#myUid()}.
*
- * @param uid
- * @return byte count
+ * @param uid The UID of the process to examine.
+ * @return number of bytes. If the statistics are not supported by this device,
+ * {@link #UNSUPPORTED} will be returned.
*/
public static long getUidTxBytes(int uid) {
return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_snd");
}
/**
- * Gets network bytes received for this UID.
+ * Get the number of bytes received through the network for this UID.
* The statistics are across all interfaces.
- * The statistics come from /proc/uid_stat.
*
* {@see android.os.Process#myUid()}.
*
- * @param uid
- * @return byte count
+ * @param uid The UID of the process to examine.
+ * @return number of bytes
*/
public static long getUidRxBytes(int uid) {
return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_rcv");
@@ -159,7 +177,7 @@
File[] nets = SYS_CLASS_NET_DIR.listFiles();
if (nets == null) {
- return 0;
+ return UNSUPPORTED;
}
long total = 0;
StringBuffer strbuf = new StringBuffer();
@@ -187,14 +205,14 @@
e);
}
}
- return 0L;
+ return UNSUPPORTED;
}
// File will have format <number><newline>
private static long getNumberFromFilePath(String filename) {
RandomAccessFile raf = getFile(filename);
if (raf == null) {
- return 0L;
+ return UNSUPPORTED;
}
return getNumberFromFile(raf, filename);
}
@@ -209,7 +227,7 @@
raf.close();
} catch (IOException e) {
Log.w(TAG, "Exception getting TCP bytes from " + filename, e);
- return 0L;
+ return UNSUPPORTED;
} finally {
if (raf != null) {
try {
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 46de708..f2e132b5 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -376,6 +376,16 @@
return sinks.toArray(new BluetoothDevice[sinks.size()]);
}
+ public synchronized BluetoothDevice[] getNonDisconnectedSinks() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ Set<BluetoothDevice> sinks = lookupSinksMatchingStates(
+ new int[] {BluetoothA2dp.STATE_CONNECTED,
+ BluetoothA2dp.STATE_PLAYING,
+ BluetoothA2dp.STATE_CONNECTING,
+ BluetoothA2dp.STATE_DISCONNECTING});
+ return sinks.toArray(new BluetoothDevice[sinks.size()]);
+ }
+
public synchronized int getSinkState(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Integer state = mAudioDevices.get(device);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e960491..0d0d245 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -546,12 +546,14 @@
boolean authorized = false;
ParcelUuid uuid = ParcelUuid.fromString(deviceUuid);
+ BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+
// Bluez sends the UUID of the local service being accessed, _not_ the
// remote service
if (mBluetoothService.isEnabled() &&
(BluetoothUuid.isAudioSource(uuid) || BluetoothUuid.isAvrcpTarget(uuid)
- || BluetoothUuid.isAdvAudioDist(uuid))) {
- BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+ || BluetoothUuid.isAdvAudioDist(uuid)) &&
+ (a2dp.getNonDisconnectedSinks().size() == 0)) {
BluetoothDevice device = mAdapter.getRemoteDevice(address);
authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
if (authorized) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1fc3678..d94d0c2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5961,7 +5961,11 @@
protected void onRestoreInstanceState(Parcelable state) {
mPrivateFlags |= SAVE_STATE_CALLED;
if (state != BaseSavedState.EMPTY_STATE && state != null) {
- throw new IllegalArgumentException("Wrong state class -- expecting View State");
+ throw new IllegalArgumentException("Wrong state class, expecting View State but "
+ + "received " + state.getClass().toString() + " instead. This usually happens "
+ + "when two views of different type have the same id in the same hierarchy. "
+ + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
+ + "other views do not use the same id.");
}
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 4baf612..2fd974e 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1300,7 +1300,7 @@
}
}
- private static Object resolveId(Context context, int id) {
+ static Object resolveId(Context context, int id) {
Object fieldValue;
final Resources resources = context.getResources();
if (id >= 0) {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index fb369d3..ee26218 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -108,6 +108,8 @@
private static final int RECEIVED_TOUCH_ICON_URL = 132;
private static final int GET_VISITED_HISTORY = 133;
private static final int OPEN_FILE_CHOOSER = 134;
+ private static final int SHOW_CUSTOM_VIEW = 135;
+ private static final int HIDE_CUSTOM_VIEW = 136;
// Message triggered by the client to resume execution
private static final int NOTIFY = 200;
@@ -679,6 +681,23 @@
mWebChromeClient.openFileChooser((UploadFile) msg.obj);
}
break;
+
+ case SHOW_CUSTOM_VIEW:
+ if (mWebChromeClient != null) {
+ HashMap<String, Object> map =
+ (HashMap<String, Object>) msg.obj;
+ View view = (View) map.get("view");
+ WebChromeClient.CustomViewCallback callback =
+ (WebChromeClient.CustomViewCallback) map.get("callback");
+ mWebChromeClient.onShowCustomView(view, callback);
+ }
+ break;
+
+ case HIDE_CUSTOM_VIEW:
+ if (mWebChromeClient != null) {
+ mWebChromeClient.onHideCustomView();
+ }
+ break;
}
}
@@ -1385,4 +1404,24 @@
}
return uploadFile.getResult();
}
+
+ /* package */ void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {
+ if (mWebChromeClient == null) {
+ return;
+ }
+ Message msg = obtainMessage(SHOW_CUSTOM_VIEW);
+ HashMap<String, Object> map = new HashMap();
+ map.put("view", view);
+ map.put("callback", callback);
+ msg.obj = map;
+ sendMessage(msg);
+ }
+
+ /* package */ void hideCustomView() {
+ if (mWebChromeClient == null) {
+ return;
+ }
+ Message msg = obtainMessage(HIDE_CUSTOM_VIEW);
+ sendMessage(msg);
+ }
}
diff --git a/core/java/android/webkit/PluginActivity.java b/core/java/android/webkit/PluginActivity.java
deleted file mode 100644
index c60512b..0000000
--- a/core/java/android/webkit/PluginActivity.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 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.webkit;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.webkit.plugin.SurfaceDrawingModel;
-import android.webkit.plugin.WebkitPlugin;
-
-/**
- * This activity is invoked when a plugin elects to go into full screen mode.
- * @hide
- */
-public class PluginActivity extends Activity {
-
- private static final String LOGTAG = "PluginActivity";
-
- /* package */ static final String INTENT_EXTRA_NPP_INSTANCE =
- "android.webkit.plugin.NPP_INSTANCE";
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final Intent intent = getIntent();
- if (intent == null) {
- Log.e(LOGTAG, "Unable to retrieve the intent responsible for this activity");
- finish();
- return;
- }
-
- final int npp = intent.getIntExtra(INTENT_EXTRA_NPP_INSTANCE, -1);
-
- if (npp == -1) {
- Log.e(LOGTAG, "The intent did not include the NPP pointer");
- finish();
- return;
- }
-
- // retrieve the plugin's existing java object instead of creating a new one
- WebkitPlugin plugin = nativeGetWebkitPlugin(npp);
-
- if (plugin == null) {
- Log.e(LOGTAG, "Unable to retrieve the plugin's java interface");
- finish();
- return;
- }
- SurfaceDrawingModel fullScreenSurface = plugin.getFullScreenSurface();
- if (fullScreenSurface == null) {
- Log.e(LOGTAG, "The plugin returned a null value for the full-screen interface");
- finish();
- return;
- }
- View pluginView = fullScreenSurface.getSurface();
- if (pluginView != null) {
- setContentView(pluginView);
- } else {
- // No custom full-sreen view returned by the plugin, odd but
- // just in case, finish the activity.
- Log.e(LOGTAG, "The plugin's full-screen interface returned a null view");
- finish();
- }
- }
-
- native WebkitPlugin nativeGetWebkitPlugin(int npp);
-}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 924398e..608c8a24 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -789,7 +789,6 @@
// Set up a measure spec so a layout can always be recreated.
mWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
mHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
- requestFocus();
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3be6a3f..7c79fd9 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3205,6 +3205,8 @@
// Note that sendOurVisibleRect calls viewToContent, so the coordinates
// should be in content coordinates.
Rect bounds = nativeFocusCandidateNodeBounds();
+ Rect vBox = contentToViewRect(bounds);
+ mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
if (!Rect.intersects(bounds, visibleRect)) {
mWebTextView.bringIntoView();
}
@@ -3215,25 +3217,14 @@
// i.e. In the case of opening/closing the screen.
// In that case, we need to set the dimensions, but not the other
// aspects.
- // We also need to restore the selection, which gets wrecked by
- // calling setTextEntryRect.
- Spannable spannable = (Spannable) mWebTextView.getText();
- int start = Selection.getSelectionStart(spannable);
- int end = Selection.getSelectionEnd(spannable);
// If the text has been changed by webkit, update it. However, if
// there has been more UI text input, ignore it. We will receive
// another update when that text is recognized.
- if (text != null && !text.equals(spannable.toString())
+ if (text != null && !text.equals(mWebTextView.getText().toString())
&& nativeTextGeneration() == mTextGeneration) {
mWebTextView.setTextAndKeepSelection(text);
- } else {
- // FIXME: Determine whether this is necessary.
- Selection.setSelection(spannable, start, end);
}
} else {
- Rect vBox = contentToViewRect(bounds);
- mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
- vBox.height());
mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
Gravity.RIGHT : Gravity.NO_GRAVITY);
// This needs to be called before setType, which may call
@@ -3247,8 +3238,8 @@
text = "";
}
mWebTextView.setTextAndKeepSelection(text);
- mWebTextView.requestFocus();
}
+ mWebTextView.requestFocus();
}
/**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 33f3713c..6079773 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -41,6 +41,7 @@
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
+import android.webkit.plugin.FullScreenDrawingModel;
import android.webkit.plugin.SurfaceDrawingModel;
import android.webkit.plugin.WebkitPlugin;
@@ -2214,16 +2215,36 @@
return pluginManager.getPluginInstance(pkgName, npp);
}
- // called by JNI. PluginWidget function to launch an activity and overlays
- // the activity with the View provided by the plugin class.
- private void startFullScreenPluginActivity(int npp) {
+ // called by JNI. PluginWidget function to launch a full-screen view using a
+ // View object provided by the plugin class.
+ private void showFullScreenPlugin(WebkitPlugin webkitPlugin) {
if (mWebView == null) {
return;
}
- Intent intent = new Intent("android.intent.webkit.PLUGIN");
- intent.putExtra(PluginActivity.INTENT_EXTRA_NPP_INSTANCE, npp);
- mWebView.getContext().startActivity(intent);
+ final FullScreenDrawingModel surface = webkitPlugin.getFullScreenSurface();
+ if(surface == null) {
+ Log.e(LOGTAG, "Attempted to create an full-screen surface with a null drawing model");
+ return;
+ }
+
+ WebChromeClient.CustomViewCallback callback = new WebChromeClient.CustomViewCallback() {
+ public void onCustomViewHidden() {
+ if (surface != null) {
+ surface.onSurfaceRemoved();
+ }
+ }
+ };
+
+ mCallbackProxy.showCustomView(surface.getSurface(), callback);
+ }
+
+ private void hideFullScreenPlugin() {
+ if (mWebView == null) {
+ return;
+ }
+
+ mCallbackProxy.hideCustomView();
}
// called by JNI. PluginWidget functions for creating an embedded View for
diff --git a/core/java/android/webkit/plugin/FullScreenDrawingModel.java b/core/java/android/webkit/plugin/FullScreenDrawingModel.java
new file mode 100644
index 0000000..fe9d197
--- /dev/null
+++ b/core/java/android/webkit/plugin/FullScreenDrawingModel.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package android.webkit.plugin;
+
+/**
+ *
+ * @hide pending API solidification
+ */
+public interface FullScreenDrawingModel extends SurfaceDrawingModel {
+
+ public void onSurfaceRemoved();
+
+}
diff --git a/core/java/android/webkit/plugin/WebkitPlugin.java b/core/java/android/webkit/plugin/WebkitPlugin.java
index 3d13c1c..af02cdc 100644
--- a/core/java/android/webkit/plugin/WebkitPlugin.java
+++ b/core/java/android/webkit/plugin/WebkitPlugin.java
@@ -30,7 +30,7 @@
*/
public interface WebkitPlugin {
- SurfaceDrawingModel getEmbeddedSurface();
- SurfaceDrawingModel getFullScreenSurface();
+ SurfaceDrawingModel getEmbeddedSurface();
+ FullScreenDrawingModel getFullScreenSurface();
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5199ada..e964a8f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -17,8 +17,8 @@
package com.android.internal.os;
import android.bluetooth.BluetoothHeadset;
+import android.net.TrafficStats;
import android.os.BatteryStats;
-import android.os.NetStat;
import android.os.Parcel;
import android.os.ParcelFormatException;
import android.os.Parcelable;
@@ -1022,8 +1022,8 @@
public void doUnplug(long batteryUptime, long batteryRealtime) {
for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
Uid u = mUidStats.valueAt(iu);
- u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
- u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
+ u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
+ u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
}
@@ -1031,10 +1031,10 @@
mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
}
// Track total mobile data
- doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
- doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
- doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
- doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
+ doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
+ doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
+ doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
+ doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
// Track radio awake time
mRadioDataStart = getCurrentRadioDataUptime();
mRadioDataUptime = 0;
@@ -1058,10 +1058,10 @@
for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
}
- doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
- doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
- doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
- doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
+ doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
+ doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
+ doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
+ doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
// Track radio awake time
mRadioDataUptime = getRadioDataUptime();
mRadioDataStart = -1;
@@ -1519,7 +1519,7 @@
public long computeCurrentTcpBytesReceived() {
return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
- ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
+ ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
}
@Override
@@ -1696,7 +1696,7 @@
public long computeCurrentTcpBytesSent() {
return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
- ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
+ ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
}
void writeToParcelLocked(Parcel out, long batteryRealtime) {
@@ -2919,22 +2919,22 @@
/** Only STATS_UNPLUGGED works properly */
public long getMobileTcpBytesSent(int which) {
- return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
+ return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
}
/** Only STATS_UNPLUGGED works properly */
public long getMobileTcpBytesReceived(int which) {
- return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
+ return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
}
/** Only STATS_UNPLUGGED works properly */
public long getTotalTcpBytesSent(int which) {
- return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
+ return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
}
/** Only STATS_UNPLUGGED works properly */
public long getTotalTcpBytesReceived(int which) {
- return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
+ return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
}
@Override
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index eacf0ce..ba0bf0d 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -76,6 +76,13 @@
*/
public static final native IBinder getContextObject();
+ /**
+ * Special for system process to not allow incoming calls to run at
+ * background scheduling priority.
+ * @hide
+ */
+ public static final native void disableBackgroundScheduling(boolean disable);
+
static native final void handleGc();
public static void forceGc(String reason) {
diff --git a/core/java/com/google/android/net/GoogleHttpClient.java b/core/java/com/google/android/net/GoogleHttpClient.java
index 8a1298f..7bdc7f8 100644
--- a/core/java/com/google/android/net/GoogleHttpClient.java
+++ b/core/java/com/google/android/net/GoogleHttpClient.java
@@ -19,13 +19,14 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.net.TrafficStats;
import android.net.http.AndroidHttpClient;
import android.os.Build;
-import android.os.NetStat;
import android.os.SystemClock;
import android.provider.Checkin;
import android.util.Config;
import android.util.Log;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
@@ -45,7 +46,6 @@
import org.apache.http.impl.client.RequestWrapper;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
import java.io.IOException;
import java.net.InetAddress;
@@ -205,8 +205,8 @@
// to follow redirects, count each redirect as an additional round trip.
int uid = android.os.Process.myUid();
- long startTx = NetStat.getUidTxBytes(uid);
- long startRx = NetStat.getUidRxBytes(uid);
+ long startTx = TrafficStats.getUidTxBytes(uid);
+ long startRx = TrafficStats.getUidRxBytes(uid);
response = mClient.execute(request, context);
HttpEntity origEntity = response == null ? null : response.getEntity();
diff --git a/core/java/com/google/android/net/NetworkStatsEntity.java b/core/java/com/google/android/net/NetworkStatsEntity.java
index f5d2349..a22fa1e 100644
--- a/core/java/com/google/android/net/NetworkStatsEntity.java
+++ b/core/java/com/google/android/net/NetworkStatsEntity.java
@@ -16,11 +16,10 @@
package com.google.android.net;
-import android.os.NetStat;
+import android.net.TrafficStats;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.EventLog;
-
import org.apache.http.HttpEntity;
import org.apache.http.entity.HttpEntityWrapper;
@@ -45,8 +44,8 @@
super.close();
} finally {
long processingTime = SystemClock.elapsedRealtime() - mProcessingStartTime;
- long tx = NetStat.getUidTxBytes(mUid);
- long rx = NetStat.getUidRxBytes(mUid);
+ long tx = TrafficStats.getUidTxBytes(mUid);
+ long rx = TrafficStats.getUidRxBytes(mUid);
EventLog.writeEvent(HTTP_STATS_EVENT, mUa, mResponseLatency, processingTime,
tx - mStartTx, rx - mStartRx);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index f0885fd..627fcbf 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -670,6 +670,12 @@
android::IPCThreadState::self()->joinThreadPool();
}
+static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
+ jobject clazz, jboolean disable)
+{
+ IPCThreadState::disableBackgroundScheduling(disable ? true : false);
+}
+
static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
{
LOGV("Gc has executed, clearing binder ops");
@@ -682,6 +688,7 @@
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
+ { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 094b02d..e84f2e5 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -120,11 +120,7 @@
jint android_os_Process_myTid(JNIEnv* env, jobject clazz)
{
-#ifdef HAVE_GETTID
- return gettid();
-#else
- return getpid();
-#endif
+ return androidGetTid();
}
jint android_os_Process_getUidForName(JNIEnv* env, jobject clazz, jstring name)
@@ -191,15 +187,11 @@
void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
- if (grp > ANDROID_TGROUP_MAX || grp < 0) {
- signalExceptionForGroupError(env, clazz, EINVAL);
+ int res = androidSetThreadSchedulingGroup(pid, grp);
+ if (res != NO_ERROR) {
+ signalExceptionForGroupError(env, clazz, res == BAD_VALUE ? EINVAL : errno);
return;
}
-
- if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
- SP_BACKGROUND : SP_FOREGROUND)) {
- signalExceptionForGroupError(env, clazz, errno);
- }
}
void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
@@ -275,22 +267,15 @@
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
jint pid, jint pri)
{
- int rc = 0;
-
- if (pri >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(pid, SP_BACKGROUND);
- } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(pid, SP_FOREGROUND);
+ int rc = androidSetThreadPriority(pid, pri);
+ if (rc != 0) {
+ if (rc == INVALID_OPERATION) {
+ signalExceptionForPriorityError(env, clazz, errno);
+ } else {
+ signalExceptionForGroupError(env, clazz, errno);
+ }
}
-
- if (rc) {
- signalExceptionForGroupError(env, clazz, errno);
- return;
- }
-
- if (setpriority(PRIO_PROCESS, pid, pri) < 0) {
- signalExceptionForPriorityError(env, clazz, errno);
- }
+
//LOGI("Setting priority of %d: %d, getpriority returns %d\n",
// pid, pri, getpriority(PRIO_PROCESS, pid));
}
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index a45faad..7e365fc 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -40,6 +40,20 @@
android:textAppearance="?android:attr/textAppearanceMedium"
/>
+ <!-- emergency call button shown when sim is missing or PUKd -->
+ <Button
+ android:id="@+id/emergencyCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:layout_marginTop="10dip"
+ android:layout_marginRight="8dip"
+ android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
+ android:drawablePadding="8dip"
+ />
+
<!-- time and date -->
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
@@ -121,6 +135,7 @@
android:layout_marginLeft="24dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginTop="12dip"
+ android:drawablePadding="4dip"
/>
<com.android.internal.widget.SlidingTab
@@ -132,18 +147,5 @@
android:layout_marginBottom="80dip"
/>
- <!-- emergency call button shown when sim is missing or PUKd -->
- <Button
- android:id="@+id/emergencyCallButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/screenLocked"
- android:layout_marginTop="8dip"
- android:layout_marginLeft="24dip"
- android:drawableLeft="@drawable/ic_emergency"
- style="@style/Widget.Button.Transparent"
- android:drawablePadding="8dip"
- />
-
</RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 1001697..33afe93 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -45,6 +45,18 @@
android:textAppearance="?android:attr/textAppearanceMedium"
/>
+ <!-- emergency call button shown when sim is missing or PUKd -->
+ <Button
+ android:id="@+id/emergencyCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="20dip"
+ android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
+ android:drawablePadding="8dip"
+ />
+
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -122,19 +134,9 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center"
android:layout_marginTop="12dip"
+ android:drawablePadding="4dip"
/>
- <!-- emergency call button shown when sim is missing or PUKd -->
- <Button
- android:id="@+id/emergencyCallButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/screenLocked"
- android:layout_marginTop="8dip"
- android:drawableLeft="@drawable/ic_emergency"
- style="@style/Widget.Button.Transparent"
- android:drawablePadding="8dip"
- />
</RelativeLayout>
<!-- right side -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index f17d1ff..b6af6b2 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -90,5 +90,12 @@
<color name="sliding_tab_text_color_active">@android:color/black</color>
<color name="sliding_tab_text_color_shadow">@android:color/black</color>
+ <!-- keyguard tab -->
+ <color name="keyguard_text_color_normal">#ffffff</color>
+ <color name="keyguard_text_color_unlock">#a7d84c</color>
+ <color name="keyguard_text_color_soundoff">#ffffff</color>
+ <color name="keyguard_text_color_soundon">#e69310</color>
+ <color name="keyguard_text_color_decline">#fe0a5a</color>
+
</resources>
diff --git a/docs/html/guide/developing/tools/aidl.jd b/docs/html/guide/developing/tools/aidl.jd
index abfa8b1..19d9ea1 100644
--- a/docs/html/guide/developing/tools/aidl.jd
+++ b/docs/html/guide/developing/tools/aidl.jd
@@ -297,9 +297,9 @@
as method arguments. </li>
</ul>
<p>Here is some sample code demonstrating calling an AIDL-created service, taken
- from the Remote Activity sample in the ApiDemos project.</p>
-<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceBinding.java
- exposing_a_service}</p>
+ from the Remote Service sample in the ApiDemos project.</p>
+<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
+ calling_a_service}</p>
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 884b5c1..749a977 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -52,7 +52,7 @@
DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
- // Corresponds to tfOneWay -- an asynchronous call.
+ // Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
};
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 78306b2b..3ab985d 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -68,6 +68,13 @@
static void shutdown();
+ // Call this to disable switching threads to background scheduling when
+ // receiving incoming IPC calls. This is specifically here for the
+ // Android system process, since it expects to have background apps calling
+ // in to it but doesn't want to acquire locks in its services while in
+ // the background.
+ static void disableBackgroundScheduling(bool disable);
+
private:
IPCThreadState();
~IPCThreadState();
@@ -93,9 +100,10 @@
void* cookie);
const sp<ProcessState> mProcess;
+ const pid_t mMyThreadId;
Vector<BBinder*> mPendingStrongDerefs;
Vector<RefBase::weakref_type*> mPendingWeakDerefs;
-
+
Parcel mIn;
Parcel mOut;
status_t mLastError;
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0fc533f..130d83c 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -124,6 +124,24 @@
extern void androidSetCreateThreadFunc(android_create_thread_fn func);
+// ------------------------------------------------------------------
+// Extra functions working with raw pids.
+
+// Get pid for the current thread.
+extern pid_t androidGetTid();
+
+// Change the scheduling group of a particular thread. The group
+// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if
+// grp is out of range, else another non-zero value with errno set if
+// the operation failed.
+extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
+
+// Change the priority AND scheduling group of a particular thread. The priority
+// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
+// if the priority set failed, else another value if just the group set failed;
+// in either case errno is set.
+extern int androidSetThreadPriority(pid_t tid, int prio);
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b2a7db8..473f580 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -292,6 +292,7 @@
static bool gHaveTLS = false;
static pthread_key_t gTLS = 0;
static bool gShutdown = false;
+static bool gDisableBackgroundScheduling = false;
IPCThreadState* IPCThreadState::self()
{
@@ -332,6 +333,11 @@
}
}
+void IPCThreadState::disableBackgroundScheduling(bool disable)
+{
+ gDisableBackgroundScheduling = disable;
+}
+
sp<ProcessState> IPCThreadState::process()
{
return mProcess;
@@ -386,6 +392,11 @@
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
+ // This thread may have been spawned by a thread that was in the background
+ // scheduling group, so first we will make sure it is in the default/foreground
+ // one to avoid performing an initial transaction in the background.
+ androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+
status_t result;
do {
int32_t cmd;
@@ -427,19 +438,13 @@
}
// After executing the command, ensure that the thread is returned to the
- // default cgroup and priority before rejoining the pool. This is a failsafe
- // in case the command implementation failed to properly restore the thread's
- // scheduling parameters upon completion.
- int my_id;
-#ifdef HAVE_GETTID
- my_id = gettid();
-#else
- my_id = getpid();
-#endif
- if (!set_sched_policy(my_id, SP_FOREGROUND)) {
- // success; reset the priority as well
- setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
- }
+ // default cgroup before rejoining the pool. The driver takes care of
+ // restoring the priority, but doesn't do anything with cgroups so we
+ // need to take care of that here in userspace. Note that we do make
+ // sure to go in the foreground after executing a transaction, but
+ // there are other callbacks into user code that could have changed
+ // our group so we want to make absolutely sure it is put back.
+ androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
@@ -583,10 +588,10 @@
}
IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self())
+ : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
{
pthread_setspecific(gTLS, this);
- clearCaller();
+ clearCaller();
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
@@ -930,6 +935,17 @@
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
+ bool doBackground = !gDisableBackgroundScheduling &&
+ getpriority(PRIO_PROCESS, mMyThreadId)
+ >= ANDROID_PRIORITY_BACKGROUND;
+ if (doBackground) {
+ // We have inherited a background priority from the caller.
+ // Ensure this thread is in the background scheduling class,
+ // since the driver won't modify scheduling classes for us.
+ androidSetThreadSchedulingGroup(mMyThreadId,
+ ANDROID_TGROUP_BG_NONINTERACT);
+ }
+
//LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Parcel reply;
@@ -967,6 +983,13 @@
mCallingPid = origPid;
mCallingUid = origUid;
+ if (doBackground) {
+ // We moved to the background scheduling group to execute
+ // this transaction, so now that we are done go back in the
+ // foreground.
+ androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+ }
+
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index ec3db09..6ca2603 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -20,6 +20,8 @@
#include <utils/threads.h>
#include <utils/Log.h>
+#include <cutils/sched_policy.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
@@ -269,6 +271,53 @@
gCreateThreadFn = func;
}
+pid_t androidGetTid()
+{
+#ifdef HAVE_GETTID
+ return gettid();
+#else
+ return getpid();
+#endif
+}
+
+int androidSetThreadSchedulingGroup(pid_t tid, int grp)
+{
+ if (grp > ANDROID_TGROUP_MAX || grp < 0) {
+ return BAD_VALUE;
+ }
+
+ if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+ SP_BACKGROUND : SP_FOREGROUND)) {
+ return PERMISSION_DENIED;
+ }
+
+ return NO_ERROR;
+}
+
+int androidSetThreadPriority(pid_t tid, int pri)
+{
+ int rc = 0;
+ int lasterr = 0;
+
+ if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+ rc = set_sched_policy(tid, SP_BACKGROUND);
+ } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+ rc = set_sched_policy(tid, SP_FOREGROUND);
+ }
+
+ if (rc) {
+ lasterr = errno;
+ }
+
+ if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
+ rc = INVALID_OPERATION;
+ } else {
+ errno = lasterr;
+ }
+
+ return rc;
+}
+
namespace android {
/*
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index cd62ed1..7763549 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -875,53 +875,51 @@
synchronized(mListeners) {
boolean wasNavigating = mNavigating;
mNavigating = (status == GPS_STATUS_SESSION_BEGIN);
-
- if (wasNavigating == mNavigating) {
- return;
- }
-
- if (mNavigating) {
+
+ if (mNavigating && !mWakeLock.isHeld()) {
if (DEBUG) Log.d(TAG, "Acquiring wakelock");
mWakeLock.acquire();
}
-
- int size = mListeners.size();
- for (int i = 0; i < size; i++) {
- Listener listener = mListeners.get(i);
+
+ if (wasNavigating != mNavigating) {
+ int size = mListeners.size();
+ for (int i = 0; i < size; i++) {
+ Listener listener = mListeners.get(i);
+ try {
+ if (mNavigating) {
+ listener.mListener.onGpsStarted();
+ } else {
+ listener.mListener.onGpsStopped();
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException in reportStatus");
+ mListeners.remove(listener);
+ // adjust for size of list changing
+ size--;
+ }
+ }
+
try {
- if (mNavigating) {
- listener.mListener.onGpsStarted();
- } else {
- listener.mListener.onGpsStopped();
+ // update battery stats
+ for (int i=mClientUids.size() - 1; i >= 0; i--) {
+ int uid = mClientUids.keyAt(i);
+ if (mNavigating) {
+ mBatteryStats.noteStartGps(uid);
+ } else {
+ mBatteryStats.noteStopGps(uid);
+ }
}
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in reportStatus");
- mListeners.remove(listener);
- // adjust for size of list changing
- size--;
}
+
+ // send an intent to notify that the GPS has been enabled or disabled.
+ Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
+ intent.putExtra(EXTRA_ENABLED, mNavigating);
+ mContext.sendBroadcast(intent);
}
- try {
- // update battery stats
- for (int i=mClientUids.size() - 1; i >= 0; i--) {
- int uid = mClientUids.keyAt(i);
- if (mNavigating) {
- mBatteryStats.noteStartGps(uid);
- } else {
- mBatteryStats.noteStopGps(uid);
- }
- }
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in reportStatus");
- }
-
- // send an intent to notify that the GPS has been enabled or disabled.
- Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
- intent.putExtra(EXTRA_ENABLED, mNavigating);
- mContext.sendBroadcast(intent);
-
- if (!mNavigating) {
+ if (status == GPS_STATUS_ENGINE_OFF && mWakeLock.isHeld()) {
if (DEBUG) Log.d(TAG, "Releasing wakelock");
mWakeLock.release();
}
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 130239e..37c2450 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -70,7 +70,7 @@
return OK;
}
- fseek(mFile, SEEK_END, 0);
+ fseek(mFile, 0, SEEK_END);
*size = ftello(mFile);
return OK;
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 8dd8ea9..9dbefe4 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -33,6 +33,10 @@
namespace android {
+// Everything must match except for
+// protection, bitrate, padding, private bits and mode extension.
+static const uint32_t kMask = 0xfffe0ccf;
+
static bool get_mp3_frame_size(
uint32_t header, size_t *frame_size,
int *out_sampling_rate = NULL, int *out_channels = NULL,
@@ -60,7 +64,7 @@
if (version == 0x01) {
return false;
}
-
+
unsigned layer = (header >> 17) & 3;
if (layer == 0x00) {
@@ -199,13 +203,9 @@
}
}
- // Everything must match except for
- // protection, bitrate, padding, private bits and mode extension.
- const uint32_t kMask = 0xfffe0ccf;
-
const size_t kMaxFrameSize = 4096;
uint8_t *buffer = new uint8_t[kMaxFrameSize];
-
+
off_t pos = *inout_pos - kMaxFrameSize;
size_t buffer_offset = kMaxFrameSize;
size_t buffer_length = kMaxFrameSize;
@@ -269,7 +269,7 @@
valid = false;
break;
}
-
+
uint32_t test_header = U32_AT(tmp);
LOGV("subsequent header is %08x", test_header);
@@ -489,8 +489,9 @@
}
uint32_t header = U32_AT((const uint8_t *)buffer->data());
-
- if (get_mp3_frame_size(header, &frame_size)) {
+
+ if ((header & kMask) == (mFixedHeader & kMask)
+ && get_mp3_frame_size(header, &frame_size)) {
break;
}
diff --git a/media/libstagefright/codecs/aacdec/AACDecoder.cpp b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
index 03ac88d..5c77a3a 100644
--- a/media/libstagefright/codecs/aacdec/AACDecoder.cpp
+++ b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
@@ -17,7 +17,7 @@
mBufferGroup(NULL),
mConfig(new tPVMP4AudioDecoderExternal),
mDecoderBuf(NULL),
- mLastSeekTimeUs(0),
+ mAnchorTimeUs(0),
mNumSamplesOutput(0),
mInputBuffer(NULL) {
}
@@ -79,7 +79,7 @@
mSource->start();
- mLastSeekTimeUs = 0;
+ mAnchorTimeUs = 0;
mNumSamplesOutput = 0;
mStarted = true;
@@ -112,13 +112,16 @@
int32_t numChannels;
int32_t sampleRate;
+ int64_t durationUs;
CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
+ CHECK(srcFormat->findInt64(kKeyDuration, &durationUs));
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
meta->setInt32(kKeyChannelCount, numChannels);
meta->setInt32(kKeySampleRate, sampleRate);
+ meta->setInt64(kKeyDuration, durationUs);
return meta;
}
@@ -150,11 +153,13 @@
return err;
}
- if (seekTimeUs >= 0) {
- CHECK(mInputBuffer->meta_data()->findInt64(
- kKeyTime, &mLastSeekTimeUs));
-
+ int64_t timeUs;
+ if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
+ mAnchorTimeUs = timeUs;
mNumSamplesOutput = 0;
+ } else {
+ // We must have a new timestamp after seeking.
+ CHECK(seekTimeUs < 0);
}
}
@@ -189,7 +194,7 @@
buffer->meta_data()->setInt64(
kKeyTime,
- mLastSeekTimeUs
+ mAnchorTimeUs
+ (mNumSamplesOutput * 1000000) / mConfig->samplingRate);
mNumSamplesOutput += mConfig->frameLength;
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index d618b83..cb2788c 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -28,10 +28,6 @@
src/pvmp3_seek_synch.cpp \
src/pvmp3_stereo_proc.cpp \
src/pvmp3_reorder.cpp \
- src/pvmp3_polyphase_filter_window.cpp \
- src/pvmp3_mdct_18.cpp \
- src/pvmp3_dct_9.cpp \
- src/pvmp3_dct_16.cpp
ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES += \
@@ -39,6 +35,12 @@
src/asm/pvmp3_mdct_18_gcc.s \
src/asm/pvmp3_dct_9_gcc.s \
src/asm/pvmp3_dct_16_gcc.s
+else
+LOCAL_SRC_FILES += \
+ src/pvmp3_polyphase_filter_window.cpp \
+ src/pvmp3_mdct_18.cpp \
+ src/pvmp3_dct_9.cpp \
+ src/pvmp3_dct_16.cpp
endif
LOCAL_C_INCLUDES := \
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index 45e20dc..f9193c0 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -78,13 +78,16 @@
int32_t numChannels;
int32_t sampleRate;
+ int64_t durationUs;
CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
+ CHECK(srcFormat->findInt64(kKeyDuration, &durationUs));
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
meta->setInt32(kKeyChannelCount, numChannels);
meta->setInt32(kKeySampleRate, sampleRate);
+ meta->setInt64(kKeyDuration, durationUs);
return meta;
}
@@ -120,6 +123,9 @@
if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
mAnchorTimeUs = timeUs;
mNumSamplesOutput = 0;
+ } else {
+ // We must have a new timestamp after seeking.
+ CHECK(seekTimeUs < 0);
}
}
diff --git a/media/libstagefright/include/AACDecoder.h b/media/libstagefright/include/AACDecoder.h
index 303d854..f09addd 100644
--- a/media/libstagefright/include/AACDecoder.h
+++ b/media/libstagefright/include/AACDecoder.h
@@ -48,7 +48,7 @@
tPVMP4AudioDecoderExternal *mConfig;
void *mDecoderBuf;
- int64_t mLastSeekTimeUs;
+ int64_t mAnchorTimeUs;
int64_t mNumSamplesOutput;
MediaBuffer *mInputBuffer;
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 676e5f6..27b631e 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -100,7 +100,7 @@
private boolean mSystemReady;
private ArrayList<Intent> mDeferredBroadcasts;
- private class NetworkAttributes {
+ private static class NetworkAttributes {
/**
* Class for holding settings read from resources.
*/
@@ -108,6 +108,7 @@
public int mType;
public int mRadio;
public int mPriority;
+ public NetworkInfo.State mLastState;
public NetworkAttributes(String init) {
String fragments[] = init.split(",");
mName = fragments[0].toLowerCase();
@@ -128,6 +129,7 @@
mType = ConnectivityManager.TYPE_MOBILE_HIPRI;
}
mPriority = Integer.parseInt(fragments[2]);
+ mLastState = NetworkInfo.State.UNKNOWN;
}
public boolean isDefault() {
return (mType == mRadio);
@@ -135,7 +137,7 @@
}
NetworkAttributes[] mNetAttributes;
- private class RadioAttributes {
+ private static class RadioAttributes {
public String mName;
public int mPriority;
public int mSimultaneity;
@@ -1213,9 +1215,22 @@
switch (msg.what) {
case NetworkStateTracker.EVENT_STATE_CHANGED:
info = (NetworkInfo) msg.obj;
+ int type = info.getType();
+ NetworkInfo.State state = info.getState();
+ if(mNetAttributes[type].mLastState == state) {
+ if (DBG) {
+ // TODO - remove this after we validate the dropping doesn't break anything
+ Log.d(TAG, "Dropping ConnectivityChange for " +
+ info.getTypeName() +": " +
+ state + "/" + info.getDetailedState());
+ }
+ return;
+ }
+ mNetAttributes[type].mLastState = state;
+
if (DBG) Log.d(TAG, "ConnectivityChange for " +
info.getTypeName() + ": " +
- info.getState() + "/" + info.getDetailedState());
+ state + "/" + info.getDetailedState());
// Connectivity state changed:
// [31-13] Reserved for future use
@@ -1233,10 +1248,9 @@
if (info.getDetailedState() ==
NetworkInfo.DetailedState.FAILED) {
handleConnectionFailure(info);
- } else if (info.getState() ==
- NetworkInfo.State.DISCONNECTED) {
+ } else if (state == NetworkInfo.State.DISCONNECTED) {
handleDisconnect(info);
- } else if (info.getState() == NetworkInfo.State.SUSPENDED) {
+ } else if (state == NetworkInfo.State.SUSPENDED) {
// TODO: need to think this over.
// the logic here is, handle SUSPENDED the same as
// DISCONNECTED. The only difference being we are
@@ -1245,7 +1259,7 @@
// opportunity to handle DISCONNECTED and SUSPENDED
// differently, or not.
handleDisconnect(info);
- } else if (info.getState() == NetworkInfo.State.CONNECTED) {
+ } else if (state == NetworkInfo.State.CONNECTED) {
handleConnect(info);
}
break;
diff --git a/services/java/com/android/server/NetStatService.java b/services/java/com/android/server/NetStatService.java
index 1ea0bac..0834405 100644
--- a/services/java/com/android/server/NetStatService.java
+++ b/services/java/com/android/server/NetStatService.java
@@ -17,8 +17,8 @@
package com.android.server;
import android.content.Context;
+import android.net.TrafficStats;
import android.os.INetStatService;
-import android.os.NetStat;
public class NetStatService extends INetStatService.Stub {
@@ -27,34 +27,34 @@
}
public long getMobileTxPackets() {
- return NetStat.getMobileTxPkts();
+ return TrafficStats.getMobileTxPkts();
}
public long getMobileRxPackets() {
- return NetStat.getMobileRxPkts();
+ return TrafficStats.getMobileRxPkts();
}
public long getMobileTxBytes() {
- return NetStat.getMobileTxBytes();
+ return TrafficStats.getMobileTxBytes();
}
public long getMobileRxBytes() {
- return NetStat.getMobileRxBytes();
+ return TrafficStats.getMobileRxBytes();
}
public long getTotalTxPackets() {
- return NetStat.getTotalTxPkts();
+ return TrafficStats.getTotalTxPkts();
}
public long getTotalRxPackets() {
- return NetStat.getTotalRxPkts();
+ return TrafficStats.getTotalRxPkts();
}
public long getTotalTxBytes() {
- return NetStat.getTotalTxBytes();
+ return TrafficStats.getTotalTxBytes();
}
public long getTotalRxBytes() {
- return NetStat.getTotalRxBytes();
+ return TrafficStats.getTotalRxBytes();
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 73f930d..214ecc1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -18,6 +18,7 @@
import com.android.server.am.ActivityManagerService;
import com.android.server.status.StatusBarService;
+import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
import dalvik.system.VMRuntime;
@@ -80,6 +81,8 @@
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
+ BinderInternal.disableBackgroundScheduling(true);
+
String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 0ea832b..987a24e 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -25,6 +25,7 @@
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -62,6 +63,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Pattern;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -109,7 +111,7 @@
private int mMulticastDisabled;
private final IBatteryStats mBatteryStats;
-
+
/**
* See {@link Settings.Gservices#WIFI_IDLE_MS}. This is the default value if a
* Settings.Gservices value is not present. This timeout value is chosen as
@@ -162,7 +164,7 @@
* Last UID that asked to enable WIFI.
*/
private int mLastEnableUid = Process.myUid();
-
+
/**
* Number of allowed radio frequency channels in various regulatory domains.
* This list is sufficient for 802.11b/g networks (2.4GHz range).
@@ -177,7 +179,7 @@
mWifiStateTracker = tracker;
mWifiStateTracker.enableRssiPolling(true);
mBatteryStats = BatteryStatsService.getService();
-
+
mScanResultCache = new LinkedHashMap<String, ScanResult>(
SCAN_RESULT_CACHE_SIZE, 0.75f, true) {
/*
@@ -396,7 +398,7 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
-
+
// Update state
mWifiState = wifiState;
@@ -1380,11 +1382,16 @@
}
mPluggedType = pluggedType;
} else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
- boolean isBluetoothPlaying =
- intent.getIntExtra(
- BluetoothA2dp.EXTRA_SINK_STATE,
- BluetoothA2dp.STATE_DISCONNECTED) == BluetoothA2dp.STATE_PLAYING;
+ BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+ Set<BluetoothDevice> sinks = a2dp.getConnectedSinks();
+ boolean isBluetoothPlaying = false;
+ for (BluetoothDevice sink : sinks) {
+ if (a2dp.getSinkState(sink) == BluetoothA2dp.STATE_PLAYING) {
+ isBluetoothPlaying = true;
+ }
+ }
mWifiStateTracker.setBluetoothScanMode(isBluetoothPlaying);
+
} else {
return;
}
@@ -1396,7 +1403,7 @@
* Determines whether the Wi-Fi chipset should stay awake or be put to
* sleep. Looks at the setting for the sleep policy and the current
* conditions.
- *
+ *
* @see #shouldDeviceStayAwake(int, int)
*/
private boolean shouldWifiStayAwake(int stayAwakeConditions, int pluggedType) {
@@ -1415,7 +1422,7 @@
return shouldDeviceStayAwake(stayAwakeConditions, pluggedType);
}
}
-
+
/**
* Determine whether the bit value corresponding to {@code pluggedType} is set in
* the bit string {@code stayAwakeConditions}. Because a {@code pluggedType} value
@@ -1509,7 +1516,7 @@
intentFilter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
mContext.registerReceiver(mReceiver, intentFilter);
}
-
+
private boolean isAirplaneSensitive() {
String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
Settings.System.AIRPLANE_MODE_RADIOS);
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 2b9d18f..bee0930 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -283,7 +283,7 @@
private IBinder mBluetoothIcon;
private IconData mBluetoothData;
private int mBluetoothHeadsetState;
- private int mBluetoothA2dpState;
+ private boolean mBluetoothA2dpConnected;
private int mBluetoothPbapState;
private boolean mBluetoothEnabled;
@@ -455,7 +455,7 @@
} else {
mBluetoothEnabled = false;
}
- mBluetoothA2dpState = BluetoothA2dp.STATE_DISCONNECTED;
+ mBluetoothA2dpConnected = false;
mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled);
@@ -636,12 +636,12 @@
int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-
+
if (!mContext.getResources().getBoolean(
com.android.internal.R.bool.config_sf_slowBlur)) {
flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
}
-
+
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -1083,7 +1083,6 @@
private final void updateBluetooth(Intent intent) {
int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth;
-
String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
@@ -1092,8 +1091,12 @@
mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
BluetoothHeadset.STATE_ERROR);
} else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
- mBluetoothA2dpState = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE,
- BluetoothA2dp.STATE_DISCONNECTED);
+ BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+ if (a2dp.getConnectedSinks().size() != 0) {
+ mBluetoothA2dpConnected = true;
+ } else {
+ mBluetoothA2dpConnected = false;
+ }
} else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
BluetoothPbap.STATE_DISCONNECTED);
@@ -1101,9 +1104,7 @@
return;
}
- if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED ||
- mBluetoothA2dpState == BluetoothA2dp.STATE_CONNECTED ||
- mBluetoothA2dpState == BluetoothA2dp.STATE_PLAYING ||
+ if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth_connected;
}