ShortcutManager improve app udpate check

- Don't use lastUpdateTime for system apps since it's not reliable.

- Scan downgraded apps too.

Bug 30708050
Bug 30734178
Change-Id: I98253f4c635466197548385275ab08c5e3a1a10b
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 51c9619..827b88a 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -667,8 +667,8 @@
                 // - version code hasn't change
                 // - lastUpdateTime hasn't change
                 // - all target activities are still enabled.
-                if ((getPackageInfo().getVersionCode() >= pi.versionCode)
-                        && (getPackageInfo().getLastUpdateTime() >= pi.lastUpdateTime)
+                if ((getPackageInfo().getVersionCode() == pi.versionCode)
+                        && (getPackageInfo().getLastUpdateTime() == pi.lastUpdateTime)
                         && areAllActivitiesStillEnabled()) {
                     return false;
                 }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 558467b..44df926 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -2626,7 +2626,7 @@
         synchronized (mLock) {
             final ShortcutUser user = getUserShortcutsLocked(userId);
             user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
-            user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ false);
+            user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ true);
         }
         verifyStates();
     }
@@ -2641,7 +2641,7 @@
             user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
 
             if (isPackageInstalled(packageName, userId)) {
-                user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ false);
+                user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ true);
             }
         }
         verifyStates();
@@ -2863,7 +2863,10 @@
         for (int i = list.size() - 1; i >= 0; i--) {
             final PackageInfo pi = list.get(i);
 
-            if (pi.lastUpdateTime >= lastScanTime) {
+            // 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 (DEBUG) {
                     Slog.d(TAG, "Found updated package " + pi.packageName);
                 }
@@ -2872,6 +2875,13 @@
         }
     }
 
+    /**
+     * @return true if it's a system app with no updates.
+     */
+    private boolean isPureSystemApp(ApplicationInfo ai) {
+        return ai.isSystemApp() && !ai.isUpdatedSystemApp();
+    }
+
     private boolean isApplicationFlagSet(@NonNull String packageName, int userId, int flags) {
         final ApplicationInfo ai = injectApplicationInfoWithUninstalled(packageName, userId);
         return (ai != null) && ((ai.flags & flags) == flags);
diff --git a/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml b/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml
index 872dc3a..f7eee91 100644
--- a/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml
+++ b/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml
@@ -16,7 +16,7 @@
 <user locales="en-US" last-app-scan-time="3113976673">
     <package name="com.android.test.1" call-count="0" last-reset="1468976368772">
         <package-info version="25" last_udpate_time="1230796800000" />
-        <shortcut id="manifest-shortcut-storage" activity="com.android.test.1/com.android.test.1.Settings" title="Storage" titleid="2131625197" titlename="storage_settings" textid="0" dmessageid="0" intent="#Intent;action=android.settings.INTERNAL_STORAGE_SETTINGS;end" timestamp="1469050672334" rank="4" flags="420" icon-res="2130837747" icon-resname="drawable/ic_shortcut_storage" >
+        <shortcut id="manifest-shortcut-storage" activity="com.android.test.1/com.android.test.1.Settings" title="Storage" intent="#Intent;action=android.settings.INTERNAL_STORAGE_SETTINGS;end" timestamp="1469050672334" flags="1" >
             <intent-extras>
                 <int name="key" value="12345" />
             </intent-extras>
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 b1c0ed4..4bd0d6fb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -4149,28 +4149,7 @@
 
         ArgumentCaptor<List> shortcuts;
 
-        // First, call the event without updating the versions.
-        reset(c0);
-        reset(c10);
-
-                mService.mPackageMonitor.onReceive(getTestContext(),
-                genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
-                mService.mPackageMonitor.onReceive(getTestContext(),
-                genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10));
-
-        waitOnMainThread();
-
-        // Version not changed, so no callback.
-        verify(c0, times(0)).onShortcutsChanged(
-                eq(CALLING_PACKAGE_1),
-                any(List.class),
-                any(UserHandle.class));
-        verify(c10, times(0)).onShortcutsChanged(
-                eq(CALLING_PACKAGE_1),
-                any(List.class),
-                any(UserHandle.class));
-
-        // Next, update the version info for package 1.
+        // Update the version info for package 1.
         reset(c0);
         reset(c10);
         updatePackageVersion(CALLING_PACKAGE_1, 1);