From b3e0db50ba7e86fd8e07e0575242227d8bfc8dbb Mon Sep 17 00:00:00 2001 From: Pinyao Ting Date: Fri, 16 Apr 2021 16:52:23 -0700 Subject: [PATCH] Postponing package rescan to prevent blocking device startup ShortcutManager currently enforces a rescan of manifest shortcuts across all of the packages after OTA update. This would lead to significant delay before launcher is visible to the user when user tries to unlock for the very first time after the OTA update. This CL moves package rescan to a later timing (i.e. when non-pinned shotrcut is requested) to mitigate the delay. Bug: 151359749 Test: atest ShortcutManagerTest1 ShortcutManagerTest2 ShortcutManagerTest3 ShortcutManagerTest4 ShortcutManagerTest5 ShortcutManagerTest6 ShortcutManagerTest7 ShortcutManagerTest8 ShortcutManagerTest9 ShortcutManagerTest10 ShortcutManagerTest11 ShortcutManagerTest12 Test: atest CtsShortcutManagerTestCases Change-Id: I5f4757e660a6e971974f3ca530a81fb25d21828c --- .../android/server/pm/ShortcutPackage.java | 40 +++++++++++++++++-- .../android/server/pm/ShortcutService.java | 2 +- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index 83fe095769f06..78592bc4b7f90 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -191,6 +191,10 @@ class ShortcutPackage extends ShortcutPackageItem { private boolean mIsInitilized; + private boolean mRescanRequired; + private boolean mIsNewApp; + private List mManifestShortcuts; + private ShortcutPackage(ShortcutUser shortcutUser, int packageUserId, String packageName, ShortcutPackageInfo spi) { super(shortcutUser, packageUserId, packageName, @@ -1124,8 +1128,22 @@ class ShortcutPackage extends ShortcutPackageItem { (isNewApp ? "added" : "updated"), getPackageInfo().getVersionCode(), pi.getLongVersionCode())); } - getPackageInfo().updateFromPackageInfo(pi); + if (isAppSearchEnabled()) { + // Save the states in memory and resume package rescan when needed + mRescanRequired = true; + mIsNewApp = isNewApp; + mManifestShortcuts = newManifestShortcutList; + } else { + rescanPackage(isNewApp, newManifestShortcutList); + } + return true; // true means changed. + } + + private void rescanPackage( + final boolean isNewApp, @NonNull final List newManifestShortcutList) { + final ShortcutService s = mShortcutUser.mService; + final long newVersionCode = getPackageInfo().getVersionCode(); // See if there are any shortcuts that were prevented restoring because the app was of a @@ -1204,7 +1222,7 @@ class ShortcutPackage extends ShortcutPackageItem { // This will send a notification to the launcher, and also save . // TODO: List changed and removed manifest shortcuts and pass to packageShortcutsChanged() s.packageShortcutsChanged(getPackageName(), getPackageUserId(), null, null); - return true; // true means changed. + mManifestShortcuts = null; } private boolean publishManifestShortcuts(List newManifestShortcutList) { @@ -1699,13 +1717,25 @@ class ShortcutPackage extends ShortcutPackageItem { return result; } + private boolean hasNoShortcut() { + if (!isAppSearchEnabled()) { + return getShortcutCount() == 0; + } + final boolean[] hasAnyShortcut = new boolean[1]; + forEachShortcutStopWhen(si -> { + hasAnyShortcut[0] = true; + return true; + }); + return !hasAnyShortcut[0]; + } + @Override public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup) throws IOException, XmlPullParserException { final int size = mShortcuts.size(); final int shareTargetSize = mShareTargets.size(); - if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) { + if (hasNoShortcut() && shareTargetSize == 0 && mApiCallCount == 0) { return; // nothing to write. } @@ -2590,6 +2620,10 @@ class ShortcutPackage extends ShortcutPackageItem { if (!wasInitialized) { restoreParsedShortcuts(false); } + if (mRescanRequired) { + mRescanRequired = false; + rescanPackage(mIsNewApp, mManifestShortcuts); + } return ConcurrentUtils.waitForFutureNoInterrupt(cb.apply(session), description); } catch (Exception e) { Slog.e(TAG, "Failed to initiate app search for shortcut package " diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index a69e9db753e25..007393ab80fbf 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -1319,7 +1319,7 @@ public class ShortcutService extends IShortcutService.Stub { mUsers.put(userId, userPackages); // Also when a user's data is first accessed, scan all packages. - injectPostToHandler(() -> checkPackageChanges(userId)); + checkPackageChanges(userId); } return userPackages; }