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

Commit 00f495c3 authored by Diego Vela's avatar Diego Vela
Browse files

Revert "Restrict {AM,WM}.closeSystemDialogs()"

This reverts commit 4347ccb7.

Reason for revert: Might be causing a test brekage.

Bug: 177228919
Change-Id: I15feef56c8ff409ab971886a1494ff0e677c306f
Test: atest CtsWindowManagerDeviceTestCases:WindowMetricsActivityTests
parent 4347ccb7
Loading
Loading
Loading
Loading
+62 −4
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ import android.app.ProfilerInfo;
import android.app.WaitResult;
import android.app.backup.BackupManager.OperationType;
import android.app.backup.IBackupManager;
import android.app.compat.CompatChanges;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStatsManager;
@@ -13719,10 +13720,34 @@ public class ActivityManagerService extends IActivityManager.Stub
                            false, false, userId, "package unstartable");
                    break;
                case Intent.ACTION_CLOSE_SYSTEM_DIALOGS:
                    if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid,
                            callerPackage)) {
                    if (!canCloseSystemDialogs(callingPid, callingUid, callerApp)) {
                        // The app can't close system dialogs, throw only if it targets S+
                        if (CompatChanges.isChangeEnabled(
                                ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, callingUid)) {
                            throw new SecurityException(
                                    "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS
                                            + " broadcast from " + callerPackage + " (pid="
                                            + callingPid + ", uid=" + callingUid + ")"
                                            + " requires "
                                            + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ".");
                        } else if (CompatChanges.isChangeEnabled(
                                ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, callingUid)) {
                            Slog.w(TAG, "Permission Denial: " + intent.getAction()
                                    + " broadcast from " + callerPackage + " (pid=" + callingPid
                                    + ", uid=" + callingUid + ")"
                                    + " requires "
                                    + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS
                                    + ", dropping broadcast.");
                            // Returning success seems to be the pattern here
                            return ActivityManager.BROADCAST_SUCCESS;
                        } else {
                            Slog.w(TAG, intent.getAction()
                                    + " broadcast from " + callerPackage + " (pid=" + callingPid
                                    + ", uid=" + callingUid + ")"
                                    + " will require  "
                                    + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS
                                    + " in future builds.");
                        }
                    }
                    break;
            }
@@ -14017,6 +14042,39 @@ public class ActivityManagerService extends IActivityManager.Stub
        return ActivityManager.BROADCAST_SUCCESS;
    }
    private boolean canCloseSystemDialogs(int pid, int uid, @Nullable ProcessRecord callerApp) {
        if (checkPermission(permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, pid, uid)
                == PERMISSION_GRANTED) {
            return true;
        }
        if (callerApp == null) {
            synchronized (mPidsSelfLocked) {
                callerApp = mPidsSelfLocked.get(pid);
            }
        }
        if (callerApp != null) {
            // Check if the instrumentation of the process has the permission. This covers the usual
            // test started from the shell (which has the permission) case. This is needed for apps
            // targeting SDK level < S but we are also allowing for targetSdk S+ as a convenience to
            // avoid breaking a bunch of existing tests and asking them to adopt shell permissions
            // to do this.
            ActiveInstrumentation instrumentation = callerApp.getActiveInstrumentation();
            if (instrumentation != null && checkPermission(
                    permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, -1, instrumentation.mSourceUid)
                    == PERMISSION_GRANTED) {
                return true;
            }
            // This is the notification trampoline use-case for example, where apps use Intent.ACSD
            // to close the shade prior to starting an activity.
            WindowProcessController wmApp = callerApp.getWindowProcessController();
            if (wmApp.canCloseSystemDialogsByToken()) {
                return true;
            }
        }
        return false;
    }
    /**
     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
     */
+1 −3
Original line number Diff line number Diff line
@@ -1435,9 +1435,7 @@ class ProcessRecord implements WindowProcessListener {
    void setActiveInstrumentation(ActiveInstrumentation instr) {
        mInstr = instr;
        boolean isInstrumenting = instr != null;
        mWindowProcessController.setInstrumenting(
                isInstrumenting,
                isInstrumenting ? instr.mSourceUid : -1,
        mWindowProcessController.setInstrumenting(isInstrumenting,
                isInstrumenting && instr.mHasBackgroundActivityStartsPermission);
    }

+0 −8
Original line number Diff line number Diff line
@@ -284,14 +284,6 @@ public abstract class ActivityTaskManagerInternal {
     */
    public abstract void enforceCallerIsRecentsOrHasPermission(String permission, String func);

    /**
     * Returns true if the app can close system dialogs. Otherwise it either throws a {@link
     * SecurityException} or returns false with a logcat message depending on whether the app
     * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not.
     */
    public abstract boolean checkCanCloseSystemDialogs(int pid, int uid,
            @Nullable String packageName);

    /**
     * Called after the voice interaction service has changed.
     */
+1 −91
Original line number Diff line number Diff line
@@ -148,7 +148,6 @@ import android.app.WindowConfiguration;
import android.app.admin.DevicePolicyCache;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.compat.CompatChanges;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
@@ -2923,86 +2922,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
    }

    /**
     * Returns true if the app can close system dialogs. Otherwise it either throws a {@link
     * SecurityException} or returns false with a logcat message depending on whether the app
     * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not.
     */
    private boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) {
        final WindowProcessController process;
        synchronized (mGlobalLock) {
            process = mProcessMap.getProcess(pid);
        }
        if (packageName == null && process != null) {
            // WindowProcessController.mInfo is final, so after the synchronized memory barrier
            // above, process.mInfo can't change. As for reading mInfo.packageName,
            // WindowProcessController doesn't own the ApplicationInfo object referenced by mInfo.
            // ProcessRecord for example also holds a reference to that object, so protecting access
            // to packageName with the WM lock would not be enough as we'd also need to synchronize
            // on the AM lock if we are worried about races, but we can't synchronize on AM lock
            // here. Hence, since this is only used for logging, we don't synchronize here.
            packageName = process.mInfo.packageName;
        }
        String caller = "(pid=" + pid + ", uid=" + uid + ")";
        if (packageName != null) {
            caller = packageName + " " + caller;
        }
        if (!canCloseSystemDialogs(pid, uid, process)) {
            // The app can't close system dialogs, throw only if it targets S+
            if (CompatChanges.isChangeEnabled(
                    ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) {
                throw new SecurityException(
                        "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS
                                + " broadcast from " + caller + " requires "
                                + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ".");
            } else if (CompatChanges.isChangeEnabled(
                    ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, uid)) {
                Slog.e(TAG,
                        "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS
                                + " broadcast from " + caller + " requires "
                                + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS
                                + ", dropping broadcast.");
                return false;
            } else {
                Slog.w(TAG, Intent.ACTION_CLOSE_SYSTEM_DIALOGS
                        + " broadcast from " + caller + " will require "
                        + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS
                        + " in future builds.");
                return true;
            }
        }
        return true;
    }

    private boolean canCloseSystemDialogs(int pid, int uid,
            @Nullable WindowProcessController process) {
        if (checkPermission(Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, pid, uid)
                == PERMISSION_GRANTED) {
            return true;
        }
        if (process != null) {
            // Check if the instrumentation of the process has the permission. This covers the
            // usual test started from the shell (which has the permission) case. This is needed
            // for apps targeting SDK level < S but we are also allowing for targetSdk S+ as a
            // convenience to avoid breaking a bunch of existing tests and asking them to adopt
            // shell permissions to do this.
            // Note that these getters all read from volatile fields in WindowProcessController, so
            // no need to lock.
            int sourceUid = process.getInstrumentationSourceUid();
            if (process.isInstrumenting() && sourceUid != -1 && checkPermission(
                    Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, -1, sourceUid)
                    == PERMISSION_GRANTED) {
                return true;
            }
            // This is the notification trampoline use-case for example, where apps use Intent.ACSD
            // to close the shade prior to starting an activity.
            if (process.canCloseSystemDialogsByToken()) {
                return true;
            }
        }
        return false;
    }

    static void enforceTaskPermission(String func) {
        if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) {
            return;
@@ -5279,12 +5198,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
        }

        @Override
        public boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) {
            return ActivityTaskManagerService.this.checkCanCloseSystemDialogs(pid, uid,
                    packageName);
        }

        @Override
        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
            synchronized (mGlobalLock) {
@@ -5785,12 +5698,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        @Override
        public void closeSystemDialogs(String reason) {
            enforceNotIsolatedCaller("closeSystemDialogs");

            final int pid = Binder.getCallingPid();
            final int uid = Binder.getCallingUid();
            if (!checkCanCloseSystemDialogs(pid, uid, null)) {
                return;
            }

            final long origId = Binder.clearCallingIdentity();
            try {
                synchronized (mGlobalLock) {
+0 −5
Original line number Diff line number Diff line
@@ -3242,11 +3242,6 @@ public class WindowManagerService extends IWindowManager.Stub

    @Override
    public void closeSystemDialogs(String reason) {
        int callingPid = Binder.getCallingPid();
        int callingUid = Binder.getCallingUid();
        if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid, null)) {
            return;
        }
        synchronized (mGlobalLock) {
            mRoot.closeSystemDialogs(reason);
        }
Loading