Merge "Add new facility to find out when a PendingIntent is canceled." into oc-dev

This commit is contained in:
TreeHugger Robot
2017-04-13 20:01:28 +00:00
committed by Android (Google) Code Review
3 changed files with 111 additions and 17 deletions

View File

@@ -190,6 +190,8 @@ interface IActivityManager {
int flags, in Bundle options, int userId);
void cancelIntentSender(in IIntentSender sender);
String getPackageForIntentSender(in IIntentSender sender);
void registerIntentSenderCancelListener(in IIntentSender sender, in IResultReceiver receiver);
void unregisterIntentSenderCancelListener(in IIntentSender sender, in IResultReceiver receiver);
void enterSafeMode();
boolean startNextMatchingActivity(in IBinder callingActivity,
in Intent intent, in Bundle options);

View File

@@ -71,7 +71,6 @@ import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
import static android.os.Process.getFreeMemory;
import static android.os.Process.getThreadPriority;
import static android.os.Process.getTotalMemory;
import static android.os.Process.isThreadInProcess;
import static android.os.Process.killProcess;
@@ -1688,6 +1687,7 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
static final int NOTIFY_VR_SLEEPING_MSG = 65;
static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
static final int START_USER_SWITCH_FG_MSG = 712;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -1956,6 +1956,18 @@ public class ActivityManagerService extends IActivityManager.Stub
case SERVICE_FOREGROUND_TIMEOUT_MSG: {
mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
} break;
case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
RemoteCallbackList<IResultReceiver> callbacks
= (RemoteCallbackList<IResultReceiver>)msg.obj;
int N = callbacks.beginBroadcast();
for (int i = 0; i < N; i++) {
try {
callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
} catch (RemoteException e) {
}
}
callbacks.finishBroadcast();
} break;
case UPDATE_TIME_ZONE: {
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -6423,7 +6435,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
didSomething = true;
it.remove();
pir.canceled = true;
makeIntentSenderCanceledLocked(pir);
if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
pir.key.activity.pendingResults.remove(pir.ref);
}
@@ -7433,7 +7445,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
return rec;
}
rec.canceled = true;
makeIntentSenderCanceledLocked(rec);
mIntentSenderRecords.remove(key);
}
if (noCreate) {
@@ -7537,7 +7549,7 @@ public class ActivityManagerService extends IActivityManager.Stub
String msg = "Permission Denial: cancelIntentSender() from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
+ " is not allowed to cancel packges "
+ " is not allowed to cancel package "
+ rec.key.packageName;
Slog.w(TAG, msg);
throw new SecurityException(msg);
@@ -7550,13 +7562,21 @@ public class ActivityManagerService extends IActivityManager.Stub
}
void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
rec.canceled = true;
makeIntentSenderCanceledLocked(rec);
mIntentSenderRecords.remove(rec.key);
if (cleanActivity && rec.key.activity != null) {
rec.key.activity.pendingResults.remove(rec.ref);
}
}
void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
rec.canceled = true;
RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
if (callbacks != null) {
mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
}
}
@Override
public String getPackageForIntentSender(IIntentSender pendingResult) {
if (!(pendingResult instanceof PendingIntentRecord)) {
@@ -7570,6 +7590,27 @@ public class ActivityManagerService extends IActivityManager.Stub
return null;
}
@Override
public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
if (!(sender instanceof PendingIntentRecord)) {
return;
}
synchronized(this) {
((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
}
}
@Override
public void unregisterIntentSenderCancelListener(IIntentSender sender,
IResultReceiver receiver) {
if (!(sender instanceof PendingIntentRecord)) {
return;
}
synchronized(this) {
((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
}
}
@Override
public int getUidForIntentSender(IIntentSender sender) {
if (sender instanceof PendingIntentRecord) {
@@ -16212,23 +16253,45 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
if (mIntentSenderRecords.size() > 0) {
Iterator<WeakReference<PendingIntentRecord>> it
// Organize these by package name, so they are easier to read.
final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
final Iterator<WeakReference<PendingIntentRecord>> it
= mIntentSenderRecords.values().iterator();
while (it.hasNext()) {
WeakReference<PendingIntentRecord> ref = it.next();
PendingIntentRecord rec = ref != null ? ref.get(): null;
if (dumpPackage != null && (rec == null
|| !dumpPackage.equals(rec.key.packageName))) {
PendingIntentRecord rec = ref != null ? ref.get() : null;
if (rec == null) {
weakRefs.add(ref);
continue;
}
if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
continue;
}
ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
if (list == null) {
list = new ArrayList<>();
byPackage.put(rec.key.packageName, list);
}
list.add(rec);
}
for (int i = 0; i < byPackage.size(); i++) {
ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
printed = true;
if (rec != null) {
pw.print(" * "); pw.println(rec);
pw.print(" * "); pw.print(byPackage.keyAt(i));
pw.print(": "); pw.print(intents.size()); pw.println(" items");
for (int j = 0; j < intents.size(); j++) {
pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
if (dumpAll) {
rec.dump(pw, " ");
intents.get(j).dump(pw, " ");
}
} else {
pw.print(" * "); pw.println(ref);
}
}
if (weakRefs.size() > 0) {
printed = true;
pw.println(" * WEAK REFS:");
for (int i = 0; i < weakRefs.size(); i++) {
pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
}
}
}
@@ -23357,7 +23420,7 @@ public class ActivityManagerService extends IActivityManager.Stub
Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
return;
}
((PendingIntentRecord) target).setWhitelistDuration(duration);
((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
}
@Override

View File

@@ -28,12 +28,14 @@ import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.TransactionTooLargeException;
import android.os.UserHandle;
import android.util.Slog;
import android.util.TimeUtils;
import com.android.internal.os.IResultReceiver;
import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import java.io.PrintWriter;
@@ -50,6 +52,7 @@ final class PendingIntentRecord extends IIntentSender.Stub {
boolean sent = false;
boolean canceled = false;
private long whitelistDuration = 0;
private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
String stringName;
String lastTagPrefix;
@@ -191,11 +194,31 @@ final class PendingIntentRecord extends IIntentSender.Stub {
ref = new WeakReference<PendingIntentRecord>(this);
}
void setWhitelistDuration(long duration) {
void setWhitelistDurationLocked(long duration) {
this.whitelistDuration = duration;
this.stringName = null;
}
public void registerCancelListenerLocked(IResultReceiver receiver) {
if (mCancelCallbacks == null) {
mCancelCallbacks = new RemoteCallbackList<>();
}
mCancelCallbacks.register(receiver);
}
public void unregisterCancelListenerLocked(IResultReceiver receiver) {
mCancelCallbacks.unregister(receiver);
if (mCancelCallbacks.getRegisteredCallbackCount() <= 0) {
mCancelCallbacks = null;
}
}
public RemoteCallbackList<IResultReceiver> detachCancelListenersLocked() {
RemoteCallbackList<IResultReceiver> listeners = mCancelCallbacks;
mCancelCallbacks = null;
return listeners;
}
public void send(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver,
String requiredPermission, Bundle options) {
sendInner(code, intent, resolvedType, finishedReceiver,
@@ -234,7 +257,6 @@ final class PendingIntentRecord extends IIntentSender.Stub {
sent = true;
if ((key.flags&PendingIntent.FLAG_ONE_SHOT) != 0) {
owner.cancelIntentSenderLocked(this, true);
canceled = true;
}
Intent finalIntent = key.requestIntent != null
@@ -398,6 +420,13 @@ final class PendingIntentRecord extends IIntentSender.Stub {
TimeUtils.formatDuration(whitelistDuration, pw);
pw.println();
}
if (mCancelCallbacks != null) {
pw.print(prefix); pw.println("mCancelCallbacks:");
for (int i = 0; i < mCancelCallbacks.getRegisteredCallbackCount(); i++) {
pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": ");
pw.println(mCancelCallbacks.getRegisteredCallbackItem(i));
}
}
}
public String toString() {