summaryrefslogtreecommitdiffstats
path: root/core/java/android/app
diff options
context:
space:
mode:
authorriddle_hsu <riddle_hsu@htc.com>2015-01-03 15:38:21 +0800
committerriddle_hsu <riddle_hsu@htc.com>2015-01-03 15:38:21 +0800
commit1f5ac4d322d76ca76fdf5dee40fe9549aad7437e (patch)
tree068aa441af936858f9764c0333a91080e46c0799 /core/java/android/app
parent38c2dae5f12003ff39a5b1a5e46f079174fcedca (diff)
downloadframeworks_base-1f5ac4d322d76ca76fdf5dee40fe9549aad7437e.zip
frameworks_base-1f5ac4d322d76ca76fdf5dee40fe9549aad7437e.tar.gz
frameworks_base-1f5ac4d322d76ca76fdf5dee40fe9549aad7437e.tar.bz2
[ActivityManager] Distinguish FG or BG receiver finished
Symptom: Assume a foreground broadcast FG and a background BG. If a recevier registers both FG and BG. When sending BG and FG to the receiver, and the receiver BG receiver completes first, its finishReceiver will trigger next FG receiver rather than BG, and also deliver wrong result code/data to the next. More detail and sample: https://code.google.com/p/android/issues/detail?id=92917 Root cause: Due to BroadcastQueue:getMatchingOrderedReceiver will match by receiver(IBinder), so the caller ActivityManagerService: broadcastRecordForReceiverLocked will always match the first queue(fg) if a receiver is both receiving fg and bg. Solution: Add a parameter flags to finishReceiver, then server side could know the finished receiver should belong to which queue. Another general solution but with bigger scope: I60dce4a48e20c1002a61a979e4d78b9b0a8b94a0 Change-Id: I913ca6f101ac8ec6c7a8e42754e6781f80247b7f
Diffstat (limited to 'core/java/android/app')
-rw-r--r--core/java/android/app/ActivityManagerNative.java7
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--core/java/android/app/LoadedApk.java6
4 files changed, 11 insertions, 7 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4e2ff0b..20355ec 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -466,8 +466,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
String resultData = data.readString();
Bundle resultExtras = data.readBundle();
boolean resultAbort = data.readInt() != 0;
+ int intentFlags = data.readInt();
if (who != null) {
- finishReceiver(who, resultCode, resultData, resultExtras, resultAbort);
+ finishReceiver(who, resultCode, resultData, resultExtras, resultAbort, intentFlags);
}
reply.writeNoException();
return true;
@@ -2807,7 +2808,8 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
- public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException
+ public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
+ boolean abortBroadcast, int flags) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -2817,6 +2819,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeString(resultData);
data.writeBundle(map);
data.writeInt(abortBroadcast ? 1 : 0);
+ data.writeInt(flags);
mRemote.transact(FINISH_RECEIVER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6233676..45304e1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -359,7 +359,7 @@ public final class ActivityThread {
public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, IBinder token, int sendingUser) {
super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
- token, sendingUser);
+ token, sendingUser, intent.getFlags());
this.intent = intent;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index be26f30..d1279ad 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -106,7 +106,8 @@ public interface IActivityManager extends IInterface {
String resultData, Bundle map, String requiredPermission,
int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException;
public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
- public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException;
+ public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
+ boolean abortBroadcast, int flags) throws RemoteException;
public void attachApplication(IApplicationThread app) throws RemoteException;
public void activityResumed(IBinder token) throws RemoteException;
public void activityIdle(IBinder token, Configuration config,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index aa98e97..973196c 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -796,7 +796,7 @@ public final class LoadedApk {
if (extras != null) {
extras.setAllowFds(false);
}
- mgr.finishReceiver(this, resultCode, data, extras, false);
+ mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
}
@@ -821,8 +821,8 @@ public final class LoadedApk {
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, int sendingUser) {
super(resultCode, resultData, resultExtras,
- mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
- ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
+ mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
+ sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
mCurIntent = intent;
mOrdered = ordered;
}