Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc04f02b authored by Dianne Hackborn's avatar Dianne Hackborn Committed by android-build-merger
Browse files

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

am: 76c71a01

Change-Id: Ieafe036ee6c2662d5897a8052facd3cd0d9fbed7
parents 108b8ec8 76c71a01
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+78 −15
Original line number Diff line number Diff line
@@ -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))) {
                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
+31 −2
Original line number Diff line number Diff line
@@ -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() {