import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Predicate;
int LAUNCHER_PERMISSION_CHECK = 4;
int CLEANUP_DANGLING_BITMAPS = 5;
int GET_ACTIVITIES_WITH_METADATA = 6;
- int GET_INSTALLED_APPLICATIONS = 7;
+ int GET_INSTALLED_PACKAGES = 7;
int CHECK_PACKAGE_CHANGES = 8;
int COUNT = CHECK_PACKAGE_CHANGES + 1;
cleanUpPackageLocked(pu.packageName, ownerUserId, pu.userId);
}
}
+ final long now = injectCurrentTimeMillis();
// Then for each installed app, publish manifest shortcuts when needed.
- forInstalledApplications(ownerUserId, ai -> {
+ forUpdatedPackages(ownerUserId, user.getLastAppScanTime(), ai -> {
user.handlePackageAddedOrUpdated(ai.packageName);
});
+
+ // 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);
+ scheduleSaveUser(ownerUserId);
}
} finally {
logDurationStat(Stats.CHECK_PACKAGE_CHANGES, start);
@Nullable
@VisibleForTesting
- List<ApplicationInfo> injectInstalledApplications(@UserIdInt int userId) {
+ List<PackageInfo> injectInstalledPackages(@UserIdInt int userId) {
final long start = injectElapsedRealtime();
final long token = injectClearCallingIdentity();
try {
- final ParceledListSlice<ApplicationInfo> parceledList =
- mIPackageManager.getInstalledApplications(PACKAGE_MATCH_FLAGS, userId);
+ final ParceledListSlice<PackageInfo> parceledList =
+ mIPackageManager.getInstalledPackages(PACKAGE_MATCH_FLAGS, userId);
if (parceledList == null) {
return Collections.emptyList();
}
} finally {
injectRestoreCallingIdentity(token);
- logDurationStat(Stats.GET_INSTALLED_APPLICATIONS, start);
+ logDurationStat(Stats.GET_INSTALLED_PACKAGES, start);
}
}
- private void forInstalledApplications(@UserIdInt int userId,
+ private void forUpdatedPackages(@UserIdInt int userId, long lastScanTime,
Consumer<ApplicationInfo> callback) {
- final List<ApplicationInfo> list = injectInstalledApplications(userId);
+ if (DEBUG) {
+ Slog.d(TAG, "forUpdatedPackages for user " + userId + ", lastScanTime=" + lastScanTime);
+ }
+ final List<PackageInfo> list = injectInstalledPackages(userId);
for (int i = list.size() - 1; i >= 0; i--) {
- final ApplicationInfo ai = list.get(i);
+ final PackageInfo pi = list.get(i);
- if ((ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
- callback.accept(ai);
+ if (((pi.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0)
+ && (pi.lastUpdateTime >= lastScanTime)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Found updated package " + pi.packageName);
+ }
+ callback.accept(pi.applicationInfo);
}
}
}
dumpStatLS(pw, p, Stats.GET_APPLICATION_INFO, "getApplicationInfo");
dumpStatLS(pw, p, Stats.CLEANUP_DANGLING_BITMAPS, "cleanupDanglingBitmaps");
dumpStatLS(pw, p, Stats.GET_ACTIVITIES_WITH_METADATA, "getActivities+metadata");
- dumpStatLS(pw, p, Stats.GET_INSTALLED_APPLICATIONS, "getInstalledApplications");
+ dumpStatLS(pw, p, Stats.GET_INSTALLED_PACKAGES, "getInstalledPackages");
dumpStatLS(pw, p, Stats.CHECK_PACKAGE_CHANGES, "checkPackageChanges");
}
private static final String ATTR_VALUE = "value";
private static final String ATTR_KNOWN_LOCALE_CHANGE_SEQUENCE_NUMBER = "locale-seq-no";
+ private static final String ATTR_LAST_APP_SCAN_TIME = "last-app-scan-time";
static final class PackageWithUser {
final int userId;
private long mKnownLocaleChangeSequenceNumber;
+ private long mLastAppScanTime;
+
public ShortcutUser(ShortcutService service, int userId) {
mService = service;
mUserId = userId;
return mUserId;
}
+ public long getLastAppScanTime() {
+ return mLastAppScanTime;
+ }
+
+ public void setLastAppScanTime(long lastAppScanTime) {
+ mLastAppScanTime = lastAppScanTime;
+ }
+
// We don't expose this directly to non-test code because only ShortcutUser should add to/
// remove from it.
@VisibleForTesting
ShortcutService.writeAttr(out, ATTR_KNOWN_LOCALE_CHANGE_SEQUENCE_NUMBER,
mKnownLocaleChangeSequenceNumber);
+ ShortcutService.writeAttr(out, ATTR_LAST_APP_SCAN_TIME,
+ mLastAppScanTime);
ShortcutService.writeTagValue(out, TAG_LAUNCHER,
mDefaultLauncherComponent);
ret.mKnownLocaleChangeSequenceNumber = ShortcutService.parseLongAttribute(parser,
ATTR_KNOWN_LOCALE_CHANGE_SEQUENCE_NUMBER);
+ // If lastAppScanTime is in the future, that means the clock went backwards.
+ // Just scan all apps again.
+ final long lastAppScanTime = ShortcutService.parseLongAttribute(parser,
+ ATTR_LAST_APP_SCAN_TIME);
+ final long currentTime = s.injectCurrentTimeMillis();
+ ret.mLastAppScanTime = lastAppScanTime < currentTime ? lastAppScanTime : 0;
+
final int outerDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
pw.print(mUserId);
pw.print(" Known locale seq#: ");
pw.print(mKnownLocaleChangeSequenceNumber);
+ pw.print(" Last app scan: ");
+ pw.print(mLastAppScanTime);
pw.println();
prefix += prefix + " ";
}
@Override
- List<ApplicationInfo> injectInstalledApplications(@UserIdInt int userId) {
- return getInstalledApplications(userId);
+ List<PackageInfo> injectInstalledPackages(@UserIdInt int userId) {
+ return getInstalledPackages(userId);
}
@Override
return ret;
}
+ private void addPackageInfo(PackageInfo pi, List<PackageInfo> list) {
+ if (pi != null) {
+ list.add(pi);
+ }
+ }
+
+ private List<PackageInfo> getInstalledPackages(int userId) {
+ final ArrayList<PackageInfo> ret = new ArrayList<>();
+
+ addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_1, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_2, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_3, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(CALLING_PACKAGE_4, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(LAUNCHER_1, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(LAUNCHER_2, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(LAUNCHER_3, userId, false), ret);
+ addPackageInfo(getInjectedPackageInfo(LAUNCHER_4, userId, false), ret);
+
+ return ret;
+ }
+
protected void addManifestShortcutResource(ComponentName activity, int resId) {
final String packageName = activity.getPackageName();
LinkedHashMap<ComponentName, Integer> map = mActivityMetadataResId.get(packageName);