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

Commit b26e2ed7 authored by Makoto Onuki's avatar Makoto Onuki Committed by android-build-merger
Browse files

Do not scan system apps unless after OTA am: 33663282

am: 140f6f5b

Change-Id: I0d37f55bb17feba629de041256ecaded338e5ca4
parents 6608a646 140f6f5b
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");