Loading services/core/java/com/android/server/pm/ShortcutService.java +51 −31 Original line number Diff line number Diff line Loading @@ -324,9 +324,29 @@ public class ShortcutService extends IShortcutService.Stub { int CHECK_LAUNCHER_ACTIVITY = 12; int IS_ACTIVITY_ENABLED = 13; int PACKAGE_UPDATE_CHECK = 14; int COUNT = PACKAGE_UPDATE_CHECK + 1; } int ASYNC_PRELOAD_USER_DELAY = 15; 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(); Loading Loading @@ -537,15 +557,22 @@ public class ShortcutService extends IShortcutService.Stub { } 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 */ Loading Loading @@ -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; } Loading Loading @@ -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()}. Loading Loading @@ -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(); Loading Loading @@ -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))); } Loading services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +11 −0 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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); Loading services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +10 −7 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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)); Loading Loading @@ -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(); Loading Loading @@ -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(); Loading @@ -4245,7 +4248,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Then send the broadcast, to only user-0. mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0)); mService.handleUnlockUser(USER_10); mService.checkPackageChanges(USER_10); waitOnMainThread(); Loading services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java +5 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } Loading @@ -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")); } Loading Loading
services/core/java/com/android/server/pm/ShortcutService.java +51 −31 Original line number Diff line number Diff line Loading @@ -324,9 +324,29 @@ public class ShortcutService extends IShortcutService.Stub { int CHECK_LAUNCHER_ACTIVITY = 12; int IS_ACTIVITY_ENABLED = 13; int PACKAGE_UPDATE_CHECK = 14; int COUNT = PACKAGE_UPDATE_CHECK + 1; } int ASYNC_PRELOAD_USER_DELAY = 15; 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(); Loading Loading @@ -537,15 +557,22 @@ public class ShortcutService extends IShortcutService.Stub { } 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 */ Loading Loading @@ -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; } Loading Loading @@ -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()}. Loading Loading @@ -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(); Loading Loading @@ -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))); } Loading
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +11 −0 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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); Loading
services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +10 −7 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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)); Loading Loading @@ -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(); Loading Loading @@ -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(); Loading @@ -4245,7 +4248,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Then send the broadcast, to only user-0. mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0)); mService.handleUnlockUser(USER_10); mService.checkPackageChanges(USER_10); waitOnMainThread(); Loading
services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java +5 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } Loading @@ -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")); } Loading