Merge "ShortcutManager: Optimize package scanning" into nyc-mr1-dev

This commit is contained in:
Makoto Onuki
2016-06-08 16:16:39 +00:00
committed by Android (Google) Code Review
3 changed files with 71 additions and 14 deletions

View File

@@ -113,6 +113,7 @@ import java.util.ArrayList;
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;
@@ -316,7 +317,7 @@ public class ShortcutService extends IShortcutService.Stub {
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;
@@ -2282,11 +2283,17 @@ public class ShortcutService extends IShortcutService.Stub {
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);
@@ -2424,12 +2431,12 @@ public class ShortcutService extends IShortcutService.Stub {
@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();
}
@@ -2441,18 +2448,25 @@ public class ShortcutService extends IShortcutService.Stub {
} 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);
}
}
}
@@ -2612,7 +2626,7 @@ public class ShortcutService extends IShortcutService.Stub {
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");
}

View File

@@ -52,6 +52,7 @@ class ShortcutUser {
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;
@@ -107,6 +108,8 @@ class ShortcutUser {
private long mKnownLocaleChangeSequenceNumber;
private long mLastAppScanTime;
public ShortcutUser(ShortcutService service, int userId) {
mService = service;
mUserId = userId;
@@ -116,6 +119,14 @@ class ShortcutUser {
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
@@ -258,6 +269,8 @@ class ShortcutUser {
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);
@@ -299,6 +312,13 @@ class ShortcutUser {
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
@@ -361,6 +381,8 @@ class ShortcutUser {
pw.print(mUserId);
pw.print(" Known locale seq#: ");
pw.print(mKnownLocaleChangeSequenceNumber);
pw.print(" Last app scan: ");
pw.print(mLastAppScanTime);
pw.println();
prefix += prefix + " ";

View File

@@ -302,8 +302,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
}
@Override
List<ApplicationInfo> injectInstalledApplications(@UserIdInt int userId) {
return getInstalledApplications(userId);
List<PackageInfo> injectInstalledPackages(@UserIdInt int userId) {
return getInstalledPackages(userId);
}
@Override
@@ -793,6 +793,27 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
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);