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

Commit 96f7306f authored by Jackal Guo's avatar Jackal Guo Committed by Android (Google) Code Review
Browse files

Merge "Apply app visibility for broadcasting distracting packages"

parents 241892df e29a9e9e
Loading
Loading
Loading
Loading
+50 −12
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.pm;

import static android.content.pm.PackageManager.RESTRICTION_NONE;
import static android.os.Process.SYSTEM_UID;

import android.annotation.NonNull;
import android.content.Intent;
@@ -27,11 +28,13 @@ import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.util.ArrayUtils;
import com.android.server.pm.pkg.PackageStateInternal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
@@ -126,7 +129,7 @@ public final class DistractingPackageHelper {
        if (!changedPackagesList.isEmpty()) {
            final String[] changedPackages = changedPackagesList.toArray(
                    new String[changedPackagesList.size()]);
            sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
            sendDistractingPackagesChanged(snapshot, changedPackages, changedUids.toArray(), userId,
                    restrictionFlags);
            mPm.scheduleWritePackageRestrictions(userId);
        }
@@ -168,7 +171,7 @@ public final class DistractingPackageHelper {
        if (!changedPackages.isEmpty()) {
            final String[] packageArray = changedPackages.toArray(
                    new String[changedPackages.size()]);
            sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId,
            sendDistractingPackagesChanged(snapshot, packageArray, changedUids.toArray(), userId,
                    RESTRICTION_NONE);
            mPm.scheduleWritePackageRestrictions(userId);
        }
@@ -181,18 +184,53 @@ public final class DistractingPackageHelper {
     * @param uidList The uids of packages which have suspension changes.
     * @param userId The user where packages reside.
     */
    void sendDistractingPackagesChanged(@NonNull String[] pkgList,
    void sendDistractingPackagesChanged(@NonNull Computer snapshot, @NonNull String[] pkgList,
            int[] uidList, int userId, int distractionFlags) {
        final Bundle extras = new Bundle(3);
        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
        extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
        final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
        final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
        final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
        final int[] userIds = new int[] {userId};
        // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if
        // allow lists are the same.
        for (int i = 0; i < pkgList.length; i++) {
            final String pkgName = pkgList[i];
            final int uid = uidList[i];
            SparseArray<int[]> allowList = mInjector.getAppsFilter().getVisibilityAllowList(
                    snapshot.getPackageStateInternal(pkgName, SYSTEM_UID),
                    userIds, snapshot.getPackageStates());
            if (allowList == null) {
                allowList = new SparseArray<>(0);
            }
            boolean merged = false;
            for (int j = 0; j < allowListsToSend.size(); j++) {
                if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) {
                    pkgsToSend.get(j).add(pkgName);
                    uidsToSend.get(j).add(uid);
                    merged = true;
                    break;
                }
            }
            if (!merged) {
                pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName)));
                uidsToSend.add(IntArray.wrap(new int[] {uid}));
                allowListsToSend.add(allowList);
            }
        }

        final Handler handler = mInjector.getHandler();
        for (int i = 0; i < pkgsToSend.size(); i++) {
            final Bundle extras = new Bundle(3);
            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
                    pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()]));
            extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
            extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
            final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
                    ? null : allowListsToSend.get(i);
            handler.post(() -> mBroadcastHelper.sendPackageBroadcast(
                Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras,
                Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
                null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
                null /* allowList */, null /* bOptions */));
                    Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */,
                    extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
                    null /* finishedReceiver */, userIds, null /* instantUserIds */,
                    allowList, null /* bOptions */));
        }
    }
}
+67 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify

@RunWith(JUnit4::class)
@@ -192,4 +193,70 @@ class DistractingPackageHelperTest : PackageHelperTestBase() {
                Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), nullable(), anyInt(),
                nullable(), nullable(), any(), nullable(), nullable(), nullable())
    }

    @Test
    fun sendDistractingPackagesChanged_withSameVisibilityAllowList() {
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, allowList(10001, 10002, 10003))

        distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
                packagesToChange, uidsToChange, TEST_USER_ID,
                PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
        testHandler.flush()
        verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED),
                nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(),
                nullable(), nullable(), nullable())

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

    @Test
    fun sendDistractingPackagesChanged_withDifferentVisibilityAllowList() {
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, allowList(10001, 10002, 10004))

        distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
                packagesToChange, uidsToChange, TEST_USER_ID,
                PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
        testHandler.flush()
        verify(broadcastHelper, times(2)).sendPackageBroadcast(
                eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(),
                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())

        bundleCaptor.allValues.forEach {
            var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
            var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
            assertThat(changedPackages?.size).isEqualTo(1)
            assertThat(changedUids?.size).isEqualTo(1)
            assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
            assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId)
        }
    }

    @Test
    fun sendDistractingPackagesChanged_withNullVisibilityAllowList() {
        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
        mockAllowList(packageSetting2, null /* list */)

        distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
                packagesToChange, uidsToChange, TEST_USER_ID,
                PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
        testHandler.flush()
        verify(broadcastHelper, times(2)).sendPackageBroadcast(
                eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(),
                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())

        bundleCaptor.allValues.forEach {
            var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
            var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
            assertThat(changedPackages?.size).isEqualTo(1)
            assertThat(changedUids?.size).isEqualTo(1)
            assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
            assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId)
        }
    }
}
 No newline at end of file
+14 −1
Original line number Diff line number Diff line
@@ -16,11 +16,12 @@

package com.android.server.pm

import android.content.pm.PackageManagerInternal
import android.os.Build
import android.os.Bundle
import android.os.UserHandle
import android.os.UserManager
import android.util.ArrayMap
import android.util.SparseArray
import com.android.server.pm.pkg.PackageStateInternal
import com.android.server.testutils.TestHandler
import com.android.server.testutils.any
@@ -32,6 +33,7 @@ import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.argThat
import org.mockito.Mockito.spy
import org.mockito.MockitoAnnotations

@@ -139,4 +141,15 @@ open class PackageHelperTestBase {
        rule.system().validateFinalState()
        return pms
    }

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

    protected fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) {
        whenever(rule.mocks().appsFilter.getVisibilityAllowList(
                argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java),
                any() as ArrayMap<String, out PackageStateInternal>
        )).thenReturn(list)
    }
}
 No newline at end of file
+0 −18
Original line number Diff line number Diff line
@@ -20,20 +20,14 @@ import android.content.Intent
import android.content.pm.SuspendDialogInfo
import android.os.Binder
import android.os.PersistableBundle
import android.util.ArrayMap
import android.util.SparseArray
import com.android.server.pm.KnownPackages
import com.android.server.pm.pkg.PackageStateInternal
import com.android.server.testutils.any
import com.android.server.testutils.eq
import com.android.server.testutils.nullable
import com.android.server.testutils.whenever
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.argThat
import org.mockito.Mockito.times
import org.mockito.Mockito.verify

@@ -383,16 +377,4 @@ class SuspendPackageHelperTest : PackageHelperTestBase() {
        assertThat(modifiedUids).asList().containsExactly(
                packageSetting1.appId, packageSetting2.appId)
    }

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

    private fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) {
        whenever(rule.mocks().appsFilter.getVisibilityAllowList(
            argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java),
            any() as ArrayMap<String, out PackageStateInternal>
        ))
            .thenReturn(list)
    }
}