diff options
-rw-r--r-- | api/current.xml | 22 | ||||
-rw-r--r-- | cmds/am/src/com/android/commands/am/Am.java | 3 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 16 | ||||
-rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 6 | ||||
-rw-r--r-- | core/java/android/app/IApplicationThread.java | 2 | ||||
-rw-r--r-- | core/java/android/app/PendingIntent.java | 2 | ||||
-rw-r--r-- | core/java/android/content/BroadcastReceiver.java | 32 | ||||
-rwxr-xr-x | core/java/android/content/IIntentReceiver.aidl | 2 | ||||
-rw-r--r-- | core/java/android/content/IntentSender.java | 2 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 21 | ||||
-rw-r--r-- | services/java/com/android/server/am/BroadcastRecord.java | 11 | ||||
-rw-r--r-- | services/java/com/android/server/am/PendingIntentRecord.java | 2 |
12 files changed, 92 insertions, 29 deletions
diff --git a/api/current.xml b/api/current.xml index e764fa5..9b0ea3a 100644 --- a/api/current.xml +++ b/api/current.xml @@ -27787,6 +27787,28 @@ <parameter name="makeMap" type="boolean"> </parameter> </method> +<method name="isInitialStickyBroadcast" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="isOrderedBroadcast" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="onReceive" return="void" abstract="true" diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 0b4f25e..eca5af9 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -340,7 +340,8 @@ public class Am { private boolean mFinished = false; public synchronized void performReceive( - Intent intent, int rc, String data, Bundle ext, boolean ord) { + Intent intent, int rc, String data, Bundle ext, boolean ord, + boolean sticky) { String line = "Broadcast completed: result=" + rc; if (data != null) line = line + ", data=\"" + data + "\""; if (ext != null) line = line + ", extras: " + ext; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index b4ac159..2cd223f 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -653,7 +653,7 @@ public final class ActivityThread { mStrongRef = strong ? rd : null; } public void performReceive(Intent intent, int resultCode, - String data, Bundle extras, boolean ordered) { + String data, Bundle extras, boolean ordered, boolean sticky) { ReceiverDispatcher rd = mDispatcher.get(); if (DEBUG_BROADCAST) { int seq = intent.getIntExtra("seq", -1); @@ -661,7 +661,8 @@ public final class ActivityThread { + " to " + rd); } if (rd != null) { - rd.performReceive(intent, resultCode, data, extras, ordered); + rd.performReceive(intent, resultCode, data, extras, + ordered, sticky); } } } @@ -681,6 +682,7 @@ public final class ActivityThread { private String mCurData; private Bundle mCurMap; private boolean mCurOrdered; + private boolean mCurSticky; public void run() { BroadcastReceiver receiver = mReceiver; @@ -706,6 +708,7 @@ public final class ActivityThread { receiver.setResult(mCurCode, mCurData, mCurMap); receiver.clearAbortBroadcast(); receiver.setOrderedHint(mCurOrdered); + receiver.setInitialStickyHint(mCurSticky); receiver.onReceive(mContext, intent); } catch (Exception e) { if (mRegistered && mCurOrdered) { @@ -788,7 +791,7 @@ public final class ActivityThread { } public void performReceive(Intent intent, int resultCode, - String data, Bundle extras, boolean ordered) { + String data, Bundle extras, boolean ordered, boolean sticky) { if (DEBUG_BROADCAST) { int seq = intent.getIntExtra("seq", -1); Log.i(TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq @@ -800,6 +803,7 @@ public final class ActivityThread { args.mCurData = data; args.mCurMap = extras; args.mCurOrdered = ordered; + args.mCurSticky = sticky; if (!mActivityThread.post(args)) { if (mRegistered) { IActivityManager mgr = ActivityManagerNative.getDefault(); @@ -1515,9 +1519,9 @@ public final class ActivityThread { // correctly ordered, since these are one-way calls and the binder driver // applies transaction ordering per object for such calls. public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, - int resultCode, String dataStr, Bundle extras, boolean ordered) - throws RemoteException { - receiver.performReceive(intent, resultCode, dataStr, extras, ordered); + int resultCode, String dataStr, Bundle extras, boolean ordered, + boolean sticky) throws RemoteException { + receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky); } public void scheduleLowMemory() { diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index 928981d..a772a8f 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -317,8 +317,9 @@ public abstract class ApplicationThreadNative extends Binder String dataStr = data.readString(); Bundle extras = data.readBundle(); boolean ordered = data.readInt() != 0; + boolean sticky = data.readInt() != 0; scheduleRegisteredReceiver(receiver, intent, - resultCode, dataStr, extras, ordered); + resultCode, dataStr, extras, ordered, sticky); return true; } @@ -716,7 +717,7 @@ class ApplicationThreadProxy implements IApplicationThread { } public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, - int resultCode, String dataStr, Bundle extras, boolean ordered) + int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); @@ -726,6 +727,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeString(dataStr); data.writeBundle(extras); data.writeInt(ordered ? 1 : 0); + data.writeInt(sticky ? 1 : 0); mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 8dda898..89a52fd 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -91,7 +91,7 @@ public interface IApplicationThread extends IInterface { void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) throws RemoteException; void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, - int resultCode, String data, Bundle extras, boolean ordered) + int resultCode, String data, Bundle extras, boolean ordered, boolean sticky) throws RemoteException; void scheduleLowMemory() throws RemoteException; void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException; diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 18d9b92..be1dc4a 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -147,7 +147,7 @@ public final class PendingIntent implements Parcelable { mHandler = handler; } public void performReceive(Intent intent, int resultCode, - String data, Bundle extras, boolean serialized) { + String data, Bundle extras, boolean serialized, boolean sticky) { mIntent = intent; mResultCode = resultCode; mResultData = data; diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java index b391c57..b63d026 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -384,6 +384,24 @@ public abstract class BroadcastReceiver { } /** + * Returns true if the receiver is currently processing an ordered + * broadcast. + */ + public final boolean isOrderedBroadcast() { + return mOrderedHint; + } + + /** + * Returns true if the receiver is currently processing the initial + * value of a sticky broadcast -- that is, the value that was last + * broadcast and is currently held in the sticky cache, so this is + * not directly the result of a broadcast right now. + */ + public final boolean isInitialStickyBroadcast() { + return mInitialStickyHint; + } + + /** * For internal use, sets the hint about whether this BroadcastReceiver is * running in ordered mode. */ @@ -392,6 +410,14 @@ public abstract class BroadcastReceiver { } /** + * For internal use, sets the hint about whether this BroadcastReceiver is + * receiving the initial sticky broadcast value. @hide + */ + public final void setInitialStickyHint(boolean isInitialSticky) { + mInitialStickyHint = isInitialSticky; + } + + /** * Control inclusion of debugging help for mismatched * calls to {@ Context#registerReceiver(BroadcastReceiver, IntentFilter) * Context.registerReceiver()}. @@ -414,7 +440,10 @@ public abstract class BroadcastReceiver { } void checkSynchronousHint() { - if (mOrderedHint) { + // Note that we don't assert when receiving the initial sticky value, + // since that may have come from an ordered broadcast. We'll catch + // them later when the real broadcast happens again. + if (mOrderedHint || mInitialStickyHint) { return; } RuntimeException e = new RuntimeException( @@ -429,5 +458,6 @@ public abstract class BroadcastReceiver { private boolean mAbortBroadcast; private boolean mDebugUnregister; private boolean mOrderedHint; + private boolean mInitialStickyHint; } diff --git a/core/java/android/content/IIntentReceiver.aidl b/core/java/android/content/IIntentReceiver.aidl index 443db2d..6f2f7c4 100755 --- a/core/java/android/content/IIntentReceiver.aidl +++ b/core/java/android/content/IIntentReceiver.aidl @@ -28,6 +28,6 @@ import android.os.Bundle; */ oneway interface IIntentReceiver { void performReceive(in Intent intent, int resultCode, - String data, in Bundle extras, boolean ordered); + String data, in Bundle extras, boolean ordered, boolean sticky); } diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java index c8f7aa9..e182021 100644 --- a/core/java/android/content/IntentSender.java +++ b/core/java/android/content/IntentSender.java @@ -113,7 +113,7 @@ public class IntentSender implements Parcelable { mHandler = handler; } public void performReceive(Intent intent, int resultCode, - String data, Bundle extras, boolean serialized) { + String data, Bundle extras, boolean serialized, boolean sticky) { mIntent = intent; mResultCode = resultCode; mResultData = data; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index cd39d0d..34302b1 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -8389,7 +8389,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (i == 0) { finisher = new IIntentReceiver.Stub() { public void performReceive(Intent intent, int resultCode, - String data, Bundle extras, boolean ordered) + String data, Bundle extras, boolean ordered, + boolean sticky) throws RemoteException { synchronized (ActivityManagerService.this) { mDidUpdate = true; @@ -11571,7 +11572,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen Intent intent = (Intent)allSticky.get(i); BroadcastRecord r = new BroadcastRecord(intent, null, null, -1, -1, null, receivers, null, 0, null, null, - false); + false, true); if (mParallelBroadcasts.size() == 0) { scheduleBroadcastsLocked(); } @@ -11796,7 +11797,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen BroadcastRecord r = new BroadcastRecord(intent, callerApp, callerPackage, callingPid, callingUid, requiredPermission, registeredReceivers, resultTo, resultCode, resultData, map, - ordered); + ordered, false); if (DEBUG_BROADCAST) Log.v( TAG, "Enqueueing parallel broadcast " + r + ": prev had " + mParallelBroadcasts.size()); @@ -11875,7 +11876,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen || resultTo != null) { BroadcastRecord r = new BroadcastRecord(intent, callerApp, callerPackage, callingPid, callingUid, requiredPermission, - receivers, resultTo, resultCode, resultData, map, ordered); + receivers, resultTo, resultCode, resultData, map, ordered, false); if (DEBUG_BROADCAST) Log.v( TAG, "Enqueueing ordered broadcast " + r + ": prev had " + mOrderedBroadcasts.size()); @@ -12179,15 +12180,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } static void performReceive(ProcessRecord app, IIntentReceiver receiver, - Intent intent, int resultCode, String data, - Bundle extras, boolean ordered) throws RemoteException { + Intent intent, int resultCode, String data, Bundle extras, + boolean ordered, boolean sticky) throws RemoteException { if (app != null && app.thread != null) { // If we have an app thread, do the call through that so it is // correctly ordered with other one-way calls. app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, - data, extras, ordered); + data, extras, ordered, sticky); } else { - receiver.performReceive(intent, resultCode, data, extras, ordered); + receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); } } @@ -12251,7 +12252,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } performReceive(filter.receiverList.app, filter.receiverList.receiver, new Intent(r.intent), r.resultCode, - r.resultData, r.resultExtras, r.ordered); + r.resultData, r.resultExtras, r.ordered, r.sticky); if (ordered) { r.state = BroadcastRecord.CALL_DONE_RECEIVE; } @@ -12384,7 +12385,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } performReceive(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode, - r.resultData, r.resultExtras, false); + r.resultData, r.resultExtras, false, false); } catch (RemoteException e) { Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); } diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java index da55049..db0a6cb 100644 --- a/services/java/com/android/server/am/BroadcastRecord.java +++ b/services/java/com/android/server/am/BroadcastRecord.java @@ -39,7 +39,9 @@ class BroadcastRecord extends Binder { final String callerPackage; // who sent this final int callingPid; // the pid of who sent this final int callingUid; // the uid of who sent this - String requiredPermission; // a permission the caller has required + final boolean ordered; // serialize the send to receivers? + final boolean sticky; // originated from existing sticky data? + final String requiredPermission; // a permission the caller has required final List receivers; // contains BroadcastFilter and ResolveInfo final IIntentReceiver resultTo; // who receives final result if non-null long dispatchTime; // when dispatch started on this set of receivers @@ -48,7 +50,6 @@ class BroadcastRecord extends Binder { String resultData; // current result data value. Bundle resultExtras; // current result extra data values. boolean resultAbort; // current result abortBroadcast value. - boolean ordered; // serialize the send to receivers? int nextReceiver; // next receiver to be executed. IBinder receiver; // who is currently running, null if none. int state; @@ -86,7 +87,7 @@ class BroadcastRecord extends Binder { + " resultCode=" + resultCode + " resultData=" + resultData); pw.println(prefix + "resultExtras=" + resultExtras); pw.println(prefix + "resultAbort=" + resultAbort - + " ordered=" + ordered); + + " ordered=" + ordered + " sticky=" + sticky); pw.println(prefix + "nextReceiver=" + nextReceiver + " receiver=" + receiver); pw.println(prefix + "curFilter=" + curFilter); @@ -122,7 +123,8 @@ class BroadcastRecord extends Binder { BroadcastRecord(Intent _intent, ProcessRecord _callerApp, String _callerPackage, int _callingPid, int _callingUid, String _requiredPermission, List _receivers, IIntentReceiver _resultTo, int _resultCode, - String _resultData, Bundle _resultExtras, boolean _serialized) { + String _resultData, Bundle _resultExtras, boolean _serialized, + boolean _sticky) { intent = _intent; callerApp = _callerApp; callerPackage = _callerPackage; @@ -135,6 +137,7 @@ class BroadcastRecord extends Binder { resultData = _resultData; resultExtras = _resultExtras; ordered = _serialized; + sticky = _sticky; nextReceiver = 0; state = IDLE; } diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java index a753d05..b3086d5 100644 --- a/services/java/com/android/server/am/PendingIntentRecord.java +++ b/services/java/com/android/server/am/PendingIntentRecord.java @@ -248,7 +248,7 @@ class PendingIntentRecord extends IIntentSender.Stub { if (sendFinish) { try { finishedReceiver.performReceive(new Intent(finalIntent), 0, - null, null, false); + null, null, false, false); } catch (RemoteException e) { } } |