From fac592f64c55004e9048e30e03d6dc65bdb4f00a Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Mon, 21 Nov 2016 13:41:32 -0800 Subject: [PATCH] Fix issue with apps restored to lower versions. When restoring to a new device, if a restored app is not compatible with the old version (e.g. lower version or different signature), then we won't restore shortcuts, which is working as expected. However when it happens, the shortcut manager forgot to "un-shadow" the package information, causing the app to not have shortcuts at all. Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests Bug 32999759 Change-Id: I89832360114de0ce1c57d763bcaccab4fdb87b6d --- .../server/pm/ShortcutPackageItem.java | 34 +++++++++++-------- .../android/server/pm/ShortcutService.java | 10 ++++++ .../server/pm/ShortcutManagerTest1.java | 9 +++++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java index 1f195a7a544b0..e59d69f4c563c 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java +++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java @@ -106,27 +106,31 @@ abstract class ShortcutPackageItem { } return; // Not installed, no need to restore yet. } + boolean blockRestore = false; if (!mPackageInfo.hasSignatures()) { s.wtf("Attempted to restore package " + mPackageName + ", user=" + mPackageUserId + " but signatures not found in the restore data."); + blockRestore = true; + } + if (!blockRestore) { + final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId); + if (!mPackageInfo.canRestoreTo(s, pi)) { + // Package is now installed, but can't restore. Let the subclass do the cleanup. + blockRestore = true; + } + } + if (blockRestore) { onRestoreBlocked(); - return; + } else { + if (ShortcutService.DEBUG) { + Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName, + mPackageUserId, getOwnerUserId())); + } + + onRestored(); } - final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId); - if (!mPackageInfo.canRestoreTo(s, pi)) { - // Package is now installed, but can't restore. Let the subclass do the cleanup. - onRestoreBlocked(); - return; - } - if (ShortcutService.DEBUG) { - Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName, - mPackageUserId, getOwnerUserId())); - } - - onRestored(); - - // Now the package is not shadow. + // Either way, it's no longer a shadow. mPackageInfo.setShadow(false); s.scheduleSaveUser(mPackageUserId); diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 500af0ca73d3b..6e8799e81326b 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -3739,6 +3739,16 @@ public class ShortcutService extends IShortcutService.Stub { } } + @VisibleForTesting + ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) { + synchronized (mLock) { + final ShortcutUser user = mUsers.get(userId); + if (user == null) return null; + + return user.getAllLaunchersForTest().get(PackageWithUser.of(userId, packageName)); + } + } + /** * Control whether {@link #verifyStates} should be performed. We always perform it during unit * tests. diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 3cfdc329a9718..cd48f36ade522 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -4938,6 +4938,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals(0, mManager.getDynamicShortcuts().size()); assertEquals(0, mManager.getPinnedShortcuts().size()); }); + assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0) + .getPackageInfo().isShadow()); + installPackage(USER_0, CALLING_PACKAGE_2); runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { @@ -4946,6 +4949,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mManager.getPinnedShortcuts()), "s1", "s2", "s3"); }); + assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_0) + .getPackageInfo().isShadow()); installPackage(USER_0, LAUNCHER_1); runWithCaller(LAUNCHER_1, USER_0, () -> { @@ -5069,6 +5074,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0)) /* empty */); }); + assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0) + .getPackageInfo().isShadow()); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertEquals(0, mManager.getDynamicShortcuts().size()); @@ -5091,6 +5098,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0)) /* empty */); }); + assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_0) + .getPackageInfo().isShadow()); installPackage(USER_0, CALLING_PACKAGE_3); runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {