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

Commit 85c10342 authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Do not scan system apps unless after OTA" into nyc-mr1-dev

parents 2c7e4d23 33663282
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -667,6 +667,12 @@ class ShortcutPackage extends ShortcutPackageItem {
                // - version code hasn't change
                // - lastUpdateTime hasn't change
                // - all target activities are still enabled.

                // Note, system apps timestamps do *not* change after OTAs.  (But they do
                // after an adb sync or a local flash.)
                // This means if a system app's version code doesn't change on an OTA,
                // we don't notice it's updated.  But that's fine since their version code *should*
                // really change on OTAs.
                if ((getPackageInfo().getVersionCode() == pi.versionCode)
                        && (getPackageInfo().getLastUpdateTime() == pi.lastUpdateTime)
                        && areAllActivitiesStillEnabled()) {
+16 −3
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.graphics.RectF;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
@@ -2659,10 +2660,14 @@ public class ShortcutService extends IShortcutService.Stub {
            boolean forceRescan) {
        final ShortcutUser user = getUserShortcutsLocked(userId);

        // Note after each OTA, we'll need to rescan all system apps, as their lastUpdateTime
        // is not reliable.
        final long now = injectCurrentTimeMillis();
        final boolean afterOta =
                !injectBuildFingerprint().equals(user.getLastAppScanOsFingerprint());

        // Then for each installed app, publish manifest shortcuts when needed.
        forUpdatedPackages(userId, lastScanTime, ai -> {
        forUpdatedPackages(userId, lastScanTime, afterOta, ai -> {
            user.attemptToRestoreIfNeededAndSave(this, ai.packageName, userId);
            user.rescanPackageIfNeeded(ai.packageName, forceRescan);
        });
@@ -2670,6 +2675,7 @@ public class ShortcutService extends IShortcutService.Stub {
        // Write the time just before the scan, because there may be apps that have just
        // been updated, and we want to catch them in the next time.
        user.setLastAppScanTime(now);
        user.setLastAppScanOsFingerprint(injectBuildFingerprint());
        scheduleSaveUser(userId);
    }

@@ -2908,7 +2914,7 @@ public class ShortcutService extends IShortcutService.Stub {
        return parceledList.getList();
    }

    private void forUpdatedPackages(@UserIdInt int userId, long lastScanTime,
    private void forUpdatedPackages(@UserIdInt int userId, long lastScanTime, boolean afterOta,
            Consumer<ApplicationInfo> callback) {
        if (DEBUG) {
            Slog.d(TAG, "forUpdatedPackages for user " + userId + ", lastScanTime=" + lastScanTime);
@@ -2920,7 +2926,8 @@ public class ShortcutService extends IShortcutService.Stub {
            // If the package has been updated since the last scan time, then scan it.
            // Also if it's a system app with no update, lastUpdateTime is not reliable, so
            // just scan it.
            if (pi.lastUpdateTime >= lastScanTime || isPureSystemApp(pi.applicationInfo)) {
            if (pi.lastUpdateTime >= lastScanTime
                    || (afterOta && isPureSystemApp(pi.applicationInfo))) {
                if (DEBUG) {
                    Slog.d(TAG, "Found updated package " + pi.packageName);
                }
@@ -3598,6 +3605,12 @@ public class ShortcutService extends IShortcutService.Stub {
        Binder.restoreCallingIdentity(token);
    }

    // Injection point.
    @VisibleForTesting
    String injectBuildFingerprint() {
        return Build.FINGERPRINT;
    }

    final void wtf(String message) {
        wtf(message, /* exception= */ null);
    }
+17 −1
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ class ShortcutUser {

    // Suffix "2" was added to force rescan all packages after the next OTA.
    private static final String ATTR_LAST_APP_SCAN_TIME = "last-app-scan-time2";
    private static final String ATTR_LAST_APP_SCAN_OS_FINGERPRINT = "last-app-scan-fp";
    private static final String KEY_USER_ID = "userId";
    private static final String KEY_LAUNCHERS = "launchers";
    private static final String KEY_PACKAGES = "packages";
@@ -125,6 +126,8 @@ class ShortcutUser {

    private long mLastAppScanTime;

    private String mLastAppScanOsFingerprint;

    public ShortcutUser(ShortcutService service, int userId) {
        mService = service;
        mUserId = userId;
@@ -142,6 +145,14 @@ class ShortcutUser {
        mLastAppScanTime = lastAppScanTime;
    }

    public String getLastAppScanOsFingerprint() {
        return mLastAppScanOsFingerprint;
    }

    public void setLastAppScanOsFingerprint(String lastAppScanOsFingerprint) {
        mLastAppScanOsFingerprint = lastAppScanOsFingerprint;
    }

    // We don't expose this directly to non-test code because only ShortcutUser should add to/
    // remove from it.
    @VisibleForTesting
@@ -318,6 +329,8 @@ class ShortcutUser {
        ShortcutService.writeAttr(out, ATTR_KNOWN_LOCALES, mKnownLocales);
        ShortcutService.writeAttr(out, ATTR_LAST_APP_SCAN_TIME,
                mLastAppScanTime);
        ShortcutService.writeAttr(out, ATTR_LAST_APP_SCAN_OS_FINGERPRINT,
                mLastAppScanOsFingerprint);

        ShortcutService.writeTagValue(out, TAG_LAUNCHER, mLastKnownLauncher);

@@ -364,7 +377,8 @@ class ShortcutUser {
                ATTR_LAST_APP_SCAN_TIME);
        final long currentTime = s.injectCurrentTimeMillis();
        ret.mLastAppScanTime = lastAppScanTime < currentTime ? lastAppScanTime : 0;

        ret.mLastAppScanOsFingerprint = ShortcutService.parseStringAttribute(parser,
                ATTR_LAST_APP_SCAN_OS_FINGERPRINT);
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -457,6 +471,8 @@ class ShortcutUser {
        pw.print(mLastAppScanTime);
        pw.print("] ");
        pw.print(ShortcutService.formatTime(mLastAppScanTime));
        pw.print("  Last app scan FP: ");
        pw.print(mLastAppScanOsFingerprint);
        pw.println();

        prefix += prefix + "  ";
+12 −0
Original line number Diff line number Diff line
@@ -406,6 +406,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
            return mSafeMode;
        }

        @Override
        String injectBuildFingerprint() {
            return mInjectedBuildFingerprint;
        }

        @Override
        void wtf(String message, Throwable th) {
            // During tests, WTF is fatal.
@@ -528,6 +533,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    protected Map<String, PackageInfo> mInjectedPackages;

    protected Set<PackageWithUser> mUninstalledPackages;
    protected Set<String> mSystemPackages;

    protected PackageManager mMockPackageManager;
    protected PackageManagerInternal mMockPackageManagerInternal;
@@ -628,6 +634,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    protected static final String PACKAGE_FALLBACK_LAUNCHER_NAME = "fallback";
    protected static final int PACKAGE_FALLBACK_LAUNCHER_PRIORITY = -999;

    protected String mInjectedBuildFingerprint = "build1";

    static {
        QUERY_ALL.setQueryFlags(
                ShortcutQuery.FLAG_GET_ALL_KINDS);
@@ -677,6 +685,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
                pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);

        mUninstalledPackages = new HashSet<>();
        mSystemPackages = new HashSet<>();

        mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");

@@ -963,6 +972,9 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        if (mUninstalledPackages.contains(PackageWithUser.of(userId, packageName))) {
            ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
        }
        if (mSystemPackages.contains(packageName)) {
            ret.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
        }

        if (getSignatures) {
            ret.signatures = pi.signatures;
+122 −0
Original line number Diff line number Diff line
@@ -4347,6 +4347,128 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
        });
    }

    public void testHandlePackageUpdate_systemAppUpdate() {

        // Package1 is a system app.  Package 2 is not a system app, so it's not scanned
        // in this test at all.
        mSystemPackages.add(CALLING_PACKAGE_1);

        // Initial state: no shortcuts.
        mService.checkPackageChanges(USER_0);

        assertEquals(mInjectedCurrentTimeMillis,
                mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
        assertEquals(mInjectedBuildFingerprint,
                mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());

        // They have no shortcuts.
        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        // Next.
        // Update the packages -- now they have 1 manifest shortcut.
        // But checkPackageChanges() don't notice it, since their version code / timestamp haven't
        // changed.
        addManifestShortcutResource(
                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                R.xml.shortcut_1);
        addManifestShortcutResource(
                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
                R.xml.shortcut_1);
        mInjectedCurrentTimeMillis += 1000;
        mService.checkPackageChanges(USER_0);

        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });
        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        // Next.
        // Update the build finger print.  All system apps will be scanned now.
        mInjectedBuildFingerprint = "update1";
        mInjectedCurrentTimeMillis += 1000;
        mService.checkPackageChanges(USER_0);

        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .haveIds("ms1");
        });
        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        // Next.
        // Update manifest shortcuts.
        mInjectedBuildFingerprint = "update2";
        addManifestShortcutResource(
                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                R.xml.shortcut_2);
        addManifestShortcutResource(
                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
                R.xml.shortcut_2);
        mInjectedCurrentTimeMillis += 1000;
        mService.checkPackageChanges(USER_0);

        // Fingerprint hasn't changed, so CALLING_PACKAGE_1 wasn't scanned.
        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .haveIds("ms1");
        });
        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        // Update the fingerprint, but CALLING_PACKAGE_1's version code hasn't changed, so
        // still not scanned.
        mInjectedBuildFingerprint = "update2";
        mInjectedCurrentTimeMillis += 1000;
        mService.checkPackageChanges(USER_0);

        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .haveIds("ms1");
        });
        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        // Now update the version code, so CALLING_PACKAGE_1 is scanned again.
        mInjectedBuildFingerprint = "update3";
        mInjectedCurrentTimeMillis += 1000;
        updatePackageVersion(CALLING_PACKAGE_1, 1);
        mService.checkPackageChanges(USER_0);

        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .haveIds("ms1", "ms2");
        });
        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
            assertWith(getCallerShortcuts())
                    .isEmpty();
        });

        // Make sure getLastAppScanTime / getLastAppScanOsFingerprint are persisted.
        initService();
        assertEquals(mInjectedCurrentTimeMillis,
                mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
        assertEquals(mInjectedBuildFingerprint,
                mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
    }

    public void testHandlePackageChanged() {
        final ComponentName ACTIVITY1 = new ComponentName(CALLING_PACKAGE_1, "act1");
        final ComponentName ACTIVITY2 = new ComponentName(CALLING_PACKAGE_1, "act2");