am baad552d: am 68d881cf: Fix issue #2166755: BroadcastReceiver trying to return result during a non-ordered broadcast

Merge commit 'baad552dfd6e9d244659e7509ff958ec8f449c03' into eclair-mr2-plus-aosp

* commit 'baad552dfd6e9d244659e7509ff958ec8f449c03':
  Fix issue #2166755: BroadcastReceiver trying to return result during a non-ordered broadcast
This commit is contained in:
Dianne Hackborn
2009-10-05 16:04:51 -07:00
committed by Android Git Automerger
12 changed files with 92 additions and 29 deletions

View File

@@ -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"

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -8390,7 +8390,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;
@@ -11572,7 +11573,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();
}
@@ -11797,7 +11798,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());
@@ -11876,7 +11877,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());
@@ -12180,15 +12181,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);
}
}
@@ -12252,7 +12253,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;
}
@@ -12385,7 +12386,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);
}

View File

@@ -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;
}

View File

@@ -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) {
}
}