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

Commit 25e73a8b authored by Varun Shah's avatar Varun Shah
Browse files

Dismiss the suspend dialog if conditions have been modified.

Whenever suspension conditions change, if there is a user-visible
suspension-related dialog, dismiss it to ensure the user is never
looking at stale information.

Bug: 169137795
Test: atest SuspendPackagesBroadcastTest#sendPackagesSuspendModifiedForUser
Test: manual (steps below)
-enable EBS, tap on suspended app to see dialog
-enable Focus mode, ensure dialog is dismissed
-tap on suspended app again to see relevent dialog,
 disable Focus mode, ensure dialog is dismissed
-tap on suspended app again to see relevant dialog,
 disable EBS, ensure dialog is dismissed correctly
-can permute enable/disable steps to further verify

Change-Id: Ib1650f910f7441498424ab4bc92185ce432ac405
parent 1f9a6225
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -2738,6 +2738,22 @@ public class Intent implements Parcelable, Cloneable {
     */
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
    public static final String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
    /**
     * Broadcast Action: One of the suspend conditions have been modified for the packages.
     * <p>Includes the following extras:
     * <ul>
     * <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages which have been modified
     * <li> {@link #EXTRA_CHANGED_UID_LIST} is the set of uids which have been modified
     * </ul>
     *
     * <p class="note">This is a protected intent that can only be sent
     * by the system. It is only sent to registered receivers.
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGES_SUSPENSION_CHANGED =
            "android.intent.action.PACKAGES_SUSPENSION_CHANGED";


    /**
    /**
     * Broadcast Action: Distracting packages have been changed.
     * Broadcast Action: Distracting packages have been changed.
+13 −10
Original line number Original line Diff line number Diff line
@@ -72,17 +72,19 @@ public class SuspendedAppActivity extends AlertActivity
    private Resources mSuspendingAppResources;
    private Resources mSuspendingAppResources;
    private SuspendDialogInfo mSuppliedDialogInfo;
    private SuspendDialogInfo mSuppliedDialogInfo;
    private Bundle mOptions;
    private Bundle mOptions;
    private BroadcastReceiver mUnsuspendReceiver = new BroadcastReceiver() {
    private BroadcastReceiver mSuspendModifiedReceiver = new BroadcastReceiver() {
        @Override
        @Override
        public void onReceive(Context context, Intent intent) {
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(intent.getAction())) {
            if (Intent.ACTION_PACKAGES_SUSPENSION_CHANGED.equals(intent.getAction())) {
                final String[] unsuspended = intent.getStringArrayExtra(
                // Suspension conditions were modified, dismiss any related visible dialogs.
                final String[] modified = intent.getStringArrayExtra(
                        Intent.EXTRA_CHANGED_PACKAGE_LIST);
                        Intent.EXTRA_CHANGED_PACKAGE_LIST);
                if (ArrayUtils.contains(unsuspended, mSuspendedPackage)) {
                if (ArrayUtils.contains(modified, mSuspendedPackage)) {
                    if (!isFinishing()) {
                    if (!isFinishing()) {
                        Slog.w(TAG, "Package " + mSuspendedPackage
                        Slog.w(TAG, "Package " + mSuspendedPackage + " has modified"
                                + " got unsuspended while the dialog was visible. Finishing.");
                                + " suspension conditions while dialog was visible. Finishing.");
                        SuspendedAppActivity.this.finish();
                        SuspendedAppActivity.this.finish();
                        // TODO (b/198201994): reload the suspend dialog to show most relevant info
                    }
                    }
                }
                }
            }
            }
@@ -245,15 +247,16 @@ public class SuspendedAppActivity extends AlertActivity


        setupAlert();
        setupAlert();


        final IntentFilter unsuspendFilter = new IntentFilter(Intent.ACTION_PACKAGES_UNSUSPENDED);
        final IntentFilter suspendModifiedFilter =
        registerReceiverAsUser(mUnsuspendReceiver, UserHandle.of(mUserId), unsuspendFilter, null,
                new IntentFilter(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED);
                null);
        registerReceiverAsUser(mSuspendModifiedReceiver, UserHandle.of(mUserId),
                suspendModifiedFilter, null, null);
    }
    }


    @Override
    @Override
    protected void onDestroy() {
    protected void onDestroy() {
        super.onDestroy();
        super.onDestroy();
        unregisterReceiver(mUnsuspendReceiver);
        unregisterReceiver(mSuspendModifiedReceiver);
    }
    }


    private void requestDismissKeyguardIfNeeded(CharSequence dismissMessage) {
    private void requestDismissKeyguardIfNeeded(CharSequence dismissMessage) {
+27 −16
Original line number Original line Diff line number Diff line
@@ -15818,8 +15818,7 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    }
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
    void sendPackagesSuspendedForUser(String intent, String[] pkgList, int[] uidList, int userId) {
            boolean suspended) {
        final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
        final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
        final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
        final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
        final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
        final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
@@ -15860,11 +15859,8 @@ public class PackageManagerService extends IPackageManager.Stub
            extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
            extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
            final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
            final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
                    ? null : allowListsToSend.get(i);
                    ? null : allowListsToSend.get(i);
            sendPackageBroadcast(
            sendPackageBroadcast(intent, null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null,
                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
                    null, userIds, null, allowList, null);
                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
                    userIds, null, allowList, null);
        }
        }
    }
    }
@@ -16178,6 +16174,8 @@ public class PackageManagerService extends IPackageManager.Stub
        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
        final IntArray changedUids = new IntArray(packageNames.length);
        final IntArray changedUids = new IntArray(packageNames.length);
        final List<String> modifiedPackagesList = new ArrayList<>(packageNames.length);
        final IntArray modifiedUids = new IntArray(packageNames.length);
        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
        final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
        final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
                userId) : null;
                userId) : null;
@@ -16205,13 +16203,14 @@ public class PackageManagerService extends IPackageManager.Stub
                unactionedPackages.add(packageName);
                unactionedPackages.add(packageName);
                continue;
                continue;
            }
            }
            boolean packageUnsuspended;
            final boolean packageUnsuspended;
            final boolean packageModified;
            synchronized (mLock) {
            synchronized (mLock) {
                if (suspended) {
                if (suspended) {
                    pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
                    packageModified = pkgSetting.addOrUpdateSuspension(callingPackage,
                            launcherExtras, userId);
                            dialogInfo, appExtras, launcherExtras, userId);
                } else {
                } else {
                    pkgSetting.removeSuspension(callingPackage, userId);
                    packageModified = pkgSetting.removeSuspension(callingPackage, userId);
                }
                }
                packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
                packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
            }
            }
@@ -16219,18 +16218,29 @@ public class PackageManagerService extends IPackageManager.Stub
                changedPackagesList.add(packageName);
                changedPackagesList.add(packageName);
                changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
                changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
            }
            }
            if (packageModified) {
                modifiedPackagesList.add(packageName);
                modifiedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
            }
        }
        }
        if (!changedPackagesList.isEmpty()) {
        if (!changedPackagesList.isEmpty()) {
            final String[] changedPackages = changedPackagesList.toArray(
            final String[] changedPackages = changedPackagesList.toArray(new String[0]);
                    new String[changedPackagesList.size()]);
            sendPackagesSuspendedForUser(
            sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
                              : Intent.ACTION_PACKAGES_UNSUSPENDED,
                    changedPackages, changedUids.toArray(), userId);
            sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
            sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
            synchronized (mLock) {
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
                scheduleWritePackageRestrictionsLocked(userId);
            }
            }
        }
        }
        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
        // Send the suspension changed broadcast to ensure suspension state is not stale.
        if (!modifiedPackagesList.isEmpty()) {
            sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
                    modifiedPackagesList.toArray(new String[0]), modifiedUids.toArray(), userId);
        }
        return unactionedPackages.toArray(new String[0]);
    }
    }
    @Override
    @Override
@@ -16359,7 +16369,8 @@ public class PackageManagerService extends IPackageManager.Stub
            final String[] packageArray = unsuspendedPackages.toArray(
            final String[] packageArray = unsuspendedPackages.toArray(
                    new String[unsuspendedPackages.size()]);
                    new String[unsuspendedPackages.size()]);
            sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
            sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
            sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
            sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_UNSUSPENDED,
                    packageArray, unsuspendedUids.toArray(), userId);
        }
        }
    }
    }
+10 −4
Original line number Original line Diff line number Diff line
@@ -455,7 +455,7 @@ public abstract class PackageSettingBase extends SettingBase {
        return state.suspendParams != null && state.suspendParams.containsKey(suspendingPackage);
        return state.suspendParams != null && state.suspendParams.containsKey(suspendingPackage);
    }
    }


    void addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo,
    boolean addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo,
            PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) {
            PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) {
        final PackageUserState existingUserState = modifyUserState(userId);
        final PackageUserState existingUserState = modifyUserState(userId);
        final PackageUserState.SuspendParams newSuspendParams =
        final PackageUserState.SuspendParams newSuspendParams =
@@ -464,21 +464,27 @@ public abstract class PackageSettingBase extends SettingBase {
        if (existingUserState.suspendParams == null) {
        if (existingUserState.suspendParams == null) {
            existingUserState.suspendParams = new ArrayMap<>();
            existingUserState.suspendParams = new ArrayMap<>();
        }
        }
        final PackageUserState.SuspendParams oldSuspendParams =
                existingUserState.suspendParams.put(suspendingPackage, newSuspendParams);
                existingUserState.suspendParams.put(suspendingPackage, newSuspendParams);
        existingUserState.suspended = true;
        existingUserState.suspended = true;
        onChanged();
        onChanged();
        return !Objects.equals(oldSuspendParams, newSuspendParams);
    }
    }


    void removeSuspension(String suspendingPackage, int userId) {
    boolean removeSuspension(String suspendingPackage, int userId) {
        boolean wasModified = false;
        final PackageUserState existingUserState = modifyUserState(userId);
        final PackageUserState existingUserState = modifyUserState(userId);
        if (existingUserState.suspendParams != null) {
        if (existingUserState.suspendParams != null) {
            existingUserState.suspendParams.remove(suspendingPackage);
            if (existingUserState.suspendParams.remove(suspendingPackage) != null) {
                wasModified = true;
            }
            if (existingUserState.suspendParams.size() == 0) {
            if (existingUserState.suspendParams.size() == 0) {
                existingUserState.suspendParams = null;
                existingUserState.suspendParams = null;
            }
            }
        }
        }
        existingUserState.suspended = (existingUserState.suspendParams != null);
        existingUserState.suspended = (existingUserState.suspendParams != null);
        onChanged();
        onChanged();
        return wasModified;
    }
    }


    void removeSuspension(Predicate<String> suspendingPackagePredicate, int userId) {
    void removeSuspension(Predicate<String> suspendingPackagePredicate, int userId) {
+22 −6
Original line number Original line Diff line number Diff line
@@ -79,8 +79,8 @@ class SuspendPackagesBroadcastTest {
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, allowList(10001, 10002, 10003))


        pms.sendPackagesSuspendedForUser(
        pms.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENDED,
                packagesToSuspend, uidsToSuspend, TEST_USER_ID, /* suspended = */ true)
                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
        verify(pms).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
        verify(pms).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
                anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())
                anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())


@@ -97,8 +97,8 @@ class SuspendPackagesBroadcastTest {
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, allowList(10001, 10002, 10007))
        mockAllowList(packageSetting2, allowList(10001, 10002, 10007))


        pms.sendPackagesSuspendedForUser(
        pms.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENDED,
                packagesToSuspend, uidsToSuspend, TEST_USER_ID, /* suspended = */ true)
                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
        verify(pms, times(2)).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
        verify(pms, times(2)).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
                anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())
                anyInt(), nullable(), nullable(), any(), nullable(), any(), nullable())


@@ -118,8 +118,8 @@ class SuspendPackagesBroadcastTest {
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, null)
        mockAllowList(packageSetting2, null)


        pms.sendPackagesSuspendedForUser(
        pms.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENDED,
                packagesToSuspend, uidsToSuspend, TEST_USER_ID, /* suspended = */ true)
                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
        verify(pms, times(2)).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
        verify(pms, times(2)).sendPackageBroadcast(any(), nullable(), bundleCaptor.capture(),
                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())
                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())


@@ -133,6 +133,22 @@ class SuspendPackagesBroadcastTest {
        }
        }
    }
    }


    @Test
    @Throws(Exception::class)
    fun sendPackagesSuspendModifiedForUser() {
        pms.sendPackagesSuspendedForUser(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
                packagesToSuspend, uidsToSuspend, TEST_USER_ID)
        verify(pms).sendPackageBroadcast(
                eq(Intent.ACTION_PACKAGES_SUSPENSION_CHANGED), nullable(), bundleCaptor.capture(),
                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())

        var modifiedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
        var modifiedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
        assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
        assertThat(modifiedUids).asList().containsExactly(
                packageSetting1.appId, packageSetting2.appId)
    }

    private fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply {
    private fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply {
        this.put(TEST_USER_ID, uids)
        this.put(TEST_USER_ID, uids)
    }
    }