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

Commit eeefd04f authored by George Chan's avatar George Chan
Browse files

Added ADB exception case for Background Installed Apps detection.

This is a temporary fix as it is not ideal to have initiatingPackageName
be null for ADB installed package events. There is a bug cut to
PackageManager team to address this at b/265203007. Will follow with a
long term fix once this bug is resolved.

PatchSet 5: Updated to use initiatingPackageName as that is immutable.

Change-Id: If80bb72a6cc02c73004d4e0665537255f727d0a0
Bug: 264568994
Test: atest
parent f5340028
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.usage.UsageStatsManagerInternal;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IBackgroundInstallControlService;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
@@ -183,10 +184,12 @@ public class BackgroundInstallControlService extends SystemService {
            return;
        }

        String installerPackageName = null;
        String installerPackageName;
        String initiatingPackageName;
        try {
            installerPackageName = mPackageManager
                    .getInstallSourceInfo(packageName).getInstallingPackageName();
            final InstallSourceInfo installInfo = mPackageManager.getInstallSourceInfo(packageName);
            installerPackageName = installInfo.getInstallingPackageName();
            initiatingPackageName = installInfo.getInitiatingPackageName();
        } catch (PackageManager.NameNotFoundException e) {
            Slog.w(TAG, "Package's installer not found " + packageName);
            return;
@@ -196,7 +199,8 @@ public class BackgroundInstallControlService extends SystemService {
        final long installTimestamp = System.currentTimeMillis()
                - (SystemClock.uptimeMillis() - appInfo.createTimestamp);

        if (wasForegroundInstallation(installerPackageName, userId, installTimestamp)) {
        if (installedByAdb(initiatingPackageName)
                || wasForegroundInstallation(installerPackageName, userId, installTimestamp)) {
            return;
        }

@@ -205,6 +209,12 @@ public class BackgroundInstallControlService extends SystemService {
        writeBackgroundInstalledPackagesToDisk();
    }

    // ADB sets installerPackageName to null, this creates a loophole to bypass BIC which will be
    // addressed with b/265203007
    private boolean installedByAdb(String initiatingPackageName) {
        return initiatingPackageName == null;
    }

    private boolean wasForegroundInstallation(String installerPackageName,
            int userId, long installTimestamp) {
        TreeSet<BackgroundInstallControlService.ForegroundTimeFrame> foregroundTimeFrames =
+53 −4
Original line number Diff line number Diff line
@@ -539,7 +539,8 @@ public final class BackgroundInstallControlServiceTest {
            NoSuchFieldException, PackageManager.NameNotFoundException {
        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
                /* initiatingPackageName = */ INSTALLER_NAME_1,
                /* initiatingPackageSigningInfo = */ null,
                /* originatingPackageName = */ null,
                /* installingPackageName = */ INSTALLER_NAME_1);
        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
@@ -575,7 +576,8 @@ public final class BackgroundInstallControlServiceTest {
            NoSuchFieldException, PackageManager.NameNotFoundException {
        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
                /* initiatingPackageName = */ INSTALLER_NAME_1,
                /* initiatingPackageSigningInfo = */ null,
                /* originatingPackageName = */ null,
                /* installingPackageName = */ INSTALLER_NAME_1);
        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
@@ -619,7 +621,8 @@ public final class BackgroundInstallControlServiceTest {
            NoSuchFieldException, PackageManager.NameNotFoundException {
        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
                /* initiatingPackageName = */ INSTALLER_NAME_1,
                /* initiatingPackageSigningInfo = */ null,
                /* originatingPackageName = */ null,
                /* installingPackageName = */ INSTALLER_NAME_1);
        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
@@ -667,7 +670,8 @@ public final class BackgroundInstallControlServiceTest {
            NoSuchFieldException, PackageManager.NameNotFoundException {
        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
                /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
                /* initiatingPackageName = */ INSTALLER_NAME_1,
                /* initiatingPackageSigningInfo = */ null,
                /* originatingPackageName = */ null,
                /* installingPackageName = */ INSTALLER_NAME_1);
        assertEquals(installSourceInfo.getInstallingPackageName(), INSTALLER_NAME_1);
@@ -711,7 +715,52 @@ public final class BackgroundInstallControlServiceTest {
        assertEquals(1, packages.size());
        assertTrue(packages.contains(USER_ID_1, PACKAGE_NAME_1));
    }
    @Test
    public void testHandleUsageEvent_packageAddedThroughAdb() throws
            NoSuchFieldException, PackageManager.NameNotFoundException {
        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
        InstallSourceInfo installSourceInfo = new InstallSourceInfo(
                /* initiatingPackageName = */ null, //currently ADB installer sets field to null
                /* initiatingPackageSigningInfo = */ null,
                /* originatingPackageName = */ null,
                /* installingPackageName = */ INSTALLER_NAME_1);
        // b/265203007
        when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(installSourceInfo);
        ApplicationInfo appInfo = mock(ApplicationInfo.class);

        when(mPackageManager.getApplicationInfoAsUser(
                eq(PACKAGE_NAME_1),
                any(),
                anyInt())
        ).thenReturn(appInfo);

        long createTimestamp = PACKAGE_ADD_TIMESTAMP_1
                - (System.currentTimeMillis() - SystemClock.uptimeMillis());
        FieldSetter.setField(appInfo,
                ApplicationInfo.class.getDeclaredField("createTimestamp"),
                createTimestamp);

        int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
        assertEquals(USER_ID_1, UserHandle.getUserId(uid));

        // The following  usage events generation is the same as
        // testHandleUsageEvent_packageAddedOutsideTimeFrame2 test. The only difference is that
        // for ADB installs the initiatingPackageName is null, despite being detected as a
        // background install. Since we do not want to treat side-loaded apps as background install
        // getBackgroundInstalledPackages() is expected to return null
        doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
                anyString(), anyString(), anyInt());
        generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_2);
        generateUsageEvent(Event.ACTIVITY_STOPPED,
                USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_3);

        mPackageListObserver.onPackageAdded(PACKAGE_NAME_1, uid);
        mTestLooper.dispatchAll();

        var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
        assertNull(packages);
    }
    @Test
    public void testPackageRemoved() {
        assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());