am 68d881cf: Fix issue #2166755: BroadcastReceiver trying to return result during a non-ordered broadcast
Merge commit '68d881cf2d2b252f6f795cd64d43e316a1d736e5' into eclair-mr2 * commit '68d881cf2d2b252f6f795cd64d43e316a1d736e5': Fix issue #2166755: BroadcastReceiver trying to return result during a non-ordered broadcast
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -383,6 +383,24 @@ public abstract class BroadcastReceiver {
|
||||
mAbortBroadcast = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -391,6 +409,14 @@ public abstract class BroadcastReceiver {
|
||||
mOrderedHint = isOrdered;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user