Merge "Off-load unlocking users onto a worker thread"

This commit is contained in:
TreeHugger Robot
2016-08-19 20:59:27 +00:00
committed by Android (Google) Code Review
4 changed files with 75 additions and 43 deletions

View File

@@ -324,10 +324,30 @@ public class ShortcutService extends IShortcutService.Stub {
int CHECK_LAUNCHER_ACTIVITY = 12;
int IS_ACTIVITY_ENABLED = 13;
int PACKAGE_UPDATE_CHECK = 14;
int ASYNC_PRELOAD_USER_DELAY = 15;
int COUNT = PACKAGE_UPDATE_CHECK + 1;
int COUNT = ASYNC_PRELOAD_USER_DELAY + 1;
}
private static final String[] STAT_LABELS = {
"getHomeActivities()",
"Launcher permission check",
"getPackageInfo()",
"getPackageInfo(SIG)",
"getApplicationInfo",
"cleanupDanglingBitmaps",
"getActivity+metadata",
"getInstalledPackages",
"checkPackageChanges",
"getApplicationResources",
"resourceNameLookup",
"getLauncherActivity",
"checkLauncherActivity",
"isActivityEnabled",
"packageUpdateCheck",
"asyncPreloadUserDelay"
};
final Object mStatLock = new Object();
@GuardedBy("mStatLock")
@@ -533,19 +553,26 @@ public class ShortcutService extends IShortcutService.Stub {
/** lifecycle event */
void handleUnlockUser(int userId) {
if (DEBUG) {
Slog.d(TAG, "handleUnlockUser: user=" + userId);
Slog.d(TAG, "handleUnlockUser: user=" + userId);
}
synchronized (mLock) {
mUnlockedUsers.put(userId, true);
// Preload the user's shortcuts.
// Also see if the locale has changed.
// Note as of nyc, the locale is per-user, so the locale shouldn't change
// when the user is locked. However due to b/30119489 it still happens.
getUserShortcutsLocked(userId).detectLocaleChange();
checkPackageChanges(userId);
}
// Preload the user data.
// Note, we don't use mHandler here but instead just start a new thread.
// This is because mHandler (which uses com.android.internal.os.BackgroundThread) is very
// busy at this point and this could take hundreds of milliseconds, which would be too
// late since the launcher would already have started.
// So we just create a new thread. This code runs rarely, so we don't use a thread pool
// or anything.
final long start = injectElapsedRealtime();
injectRunOnNewThread(() -> {
synchronized (mLock) {
logDurationStat(Stats.ASYNC_PRELOAD_USER_DELAY, start);
getUserShortcutsLocked(userId);
}
});
}
/** lifecycle event */
@@ -1110,6 +1137,9 @@ public class ShortcutService extends IShortcutService.Stub {
userPackages = new ShortcutUser(this, userId);
}
mUsers.put(userId, userPackages);
// Also when a user's data is first accessed, scan all packages.
checkPackageChanges(userId);
}
return userPackages;
}
@@ -1468,6 +1498,10 @@ public class ShortcutService extends IShortcutService.Stub {
mHandler.post(r);
}
void injectRunOnNewThread(Runnable r) {
new Thread(r).start();
}
/**
* @throws IllegalArgumentException if {@code numShortcuts} is bigger than
* {@link #getMaxActivityShortcuts()}.
@@ -3218,23 +3252,9 @@ public class ShortcutService extends IShortcutService.Stub {
pw.println(" Stats:");
synchronized (mStatLock) {
final String p = " ";
dumpStatLS(pw, p, Stats.GET_DEFAULT_HOME, "getHomeActivities()");
dumpStatLS(pw, p, Stats.LAUNCHER_PERMISSION_CHECK, "Launcher permission check");
dumpStatLS(pw, p, Stats.GET_PACKAGE_INFO, "getPackageInfo()");
dumpStatLS(pw, p, Stats.GET_PACKAGE_INFO_WITH_SIG, "getPackageInfo(SIG)");
dumpStatLS(pw, p, Stats.GET_APPLICATION_INFO, "getApplicationInfo");
dumpStatLS(pw, p, Stats.CLEANUP_DANGLING_BITMAPS, "cleanupDanglingBitmaps");
dumpStatLS(pw, p, Stats.GET_ACTIVITY_WITH_METADATA, "getActivity+metadata");
dumpStatLS(pw, p, Stats.GET_INSTALLED_PACKAGES, "getInstalledPackages");
dumpStatLS(pw, p, Stats.CHECK_PACKAGE_CHANGES, "checkPackageChanges");
dumpStatLS(pw, p, Stats.GET_APPLICATION_RESOURCES, "getApplicationResources");
dumpStatLS(pw, p, Stats.RESOURCE_NAME_LOOKUP, "resourceNameLookup");
dumpStatLS(pw, p, Stats.GET_LAUNCHER_ACTIVITY, "getLauncherActivity");
dumpStatLS(pw, p, Stats.CHECK_LAUNCHER_ACTIVITY, "checkLauncherActivity");
dumpStatLS(pw, p, Stats.IS_ACTIVITY_ENABLED, "isActivityEnabled");
dumpStatLS(pw, p, Stats.PACKAGE_UPDATE_CHECK, "packageUpdateCheck");
for (int i = 0; i < Stats.COUNT; i++) {
dumpStatLS(pw, " ", i);
}
}
pw.println();
@@ -3277,12 +3297,12 @@ public class ShortcutService extends IShortcutService.Stub {
return tobj.format("%Y-%m-%d %H:%M:%S");
}
private void dumpStatLS(PrintWriter pw, String prefix, int statId, String label) {
private void dumpStatLS(PrintWriter pw, String prefix, int statId) {
pw.print(prefix);
final int count = mCountStats[statId];
final long dur = mDurationStats[statId];
pw.println(String.format("%s: count=%d, total=%dms, avg=%.1fms",
label, count, dur,
STAT_LABELS[statId], count, dur,
(count == 0 ? 0 : ((double) dur) / count)));
}

View File

@@ -389,6 +389,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
runOnHandler(r);
}
@Override
void injectRunOnNewThread(Runnable r) {
runOnHandler(r);
}
@Override
void injectEnforceCallingPermission(String permission, String message) {
if (!mCallerPermissions.contains(permission)) {
@@ -921,6 +926,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
});
}
protected void setPackageLastUpdateTime(String packageName, long value) {
updatePackageInfo(packageName, pi -> {
pi.lastUpdateTime = value;
});
}
protected void uninstallPackage(int userId, String packageName) {
if (ENABLE_DUMP) {
Log.v(TAG, "Unnstall package " + packageName + " / " + userId);

View File

@@ -3945,11 +3945,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mInjectedPackages.remove(CALLING_PACKAGE_1);
mInjectedPackages.remove(CALLING_PACKAGE_3);
mService.handleUnlockUser(USER_0);
mService.checkPackageChanges(USER_0);
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0)); // ---------------
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
@@ -3961,7 +3961,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
mService.handleUnlockUser(USER_10);
mService.checkPackageChanges(USER_10);
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
@@ -4154,7 +4154,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
updatePackageVersion(CALLING_PACKAGE_1, 1);
// Then send the broadcast, to only user-0.
mService.mPackageMonitor.onReceive(getTestContext(),
mService.mPackageMonitor.onReceive(getTestContext(),
genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
waitOnMainThread();
@@ -4186,10 +4186,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mInjectedCurrentTimeMillis = START_TIME + 200;
mRunningUsers.put(USER_10, true);
mUnlockedUsers.put(USER_10, true);
reset(c0);
reset(c10);
setPackageLastUpdateTime(CALLING_PACKAGE_1, mInjectedCurrentTimeMillis);
mService.handleUnlockUser(USER_10);
mService.checkPackageChanges(USER_10);
waitOnMainThread();
@@ -4221,7 +4224,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Then send the broadcast, to only user-0.
mService.mPackageMonitor.onReceive(getTestContext(),
genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0));
mService.handleUnlockUser(USER_10);
mService.checkPackageChanges(USER_10);
waitOnMainThread();
@@ -4243,9 +4246,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
updatePackageVersion(CALLING_PACKAGE_3, 100);
// Then send the broadcast, to only user-0.
mService.mPackageMonitor.onReceive(getTestContext(),
mService.mPackageMonitor.onReceive(getTestContext(),
genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0));
mService.handleUnlockUser(USER_10);
mService.checkPackageChanges(USER_10);
waitOnMainThread();

View File

@@ -156,11 +156,10 @@ public class ShortcutManagerTestUtils {
return result;
}
public static List<String> runCommand(Instrumentation instrumentation, String command) {
private static List<String> runCommand(Instrumentation instrumentation, String command) {
return runCommand(instrumentation, command, null);
}
public static List<String> runCommand(Instrumentation instrumentation, String command,
private static List<String> runCommand(Instrumentation instrumentation, String command,
Predicate<List<String>> resultAsserter) {
Log.d(TAG, "Running command: " + command);
final List<String> result;
@@ -176,11 +175,11 @@ public class ShortcutManagerTestUtils {
return result;
}
public static void runCommandForNoOutput(Instrumentation instrumentation, String command) {
private static void runCommandForNoOutput(Instrumentation instrumentation, String command) {
runCommand(instrumentation, command, result -> result.size() == 0);
}
public static List<String> runShortcutCommand(Instrumentation instrumentation, String command,
private static List<String> runShortcutCommand(Instrumentation instrumentation, String command,
Predicate<List<String>> resultAsserter) {
return runCommand(instrumentation, "cmd shortcut " + command, resultAsserter);
}
@@ -205,8 +204,7 @@ public class ShortcutManagerTestUtils {
}
public static void setDefaultLauncher(Instrumentation instrumentation, String component) {
runCommand(instrumentation, "cmd package set-home-activity --user "
+ instrumentation.getContext().getUserId() + " " + component,
runCommand(instrumentation, "cmd package set-home-activity " + component,
result -> result.contains("Success"));
}