Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +19 −8 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ class NavigationBarApps extends LinearLayout { ComponentName appComponentName = appInfo.getComponentName(); if (!appComponentName.getPackageName().equals(packageName)) continue; if (sAppsModel.buildAppLaunchIntent(new AppInfo(appComponentName, user)) != null) { if (sAppsModel.buildAppLaunchIntent(appInfo) != null) { continue; } Loading Loading @@ -456,20 +456,31 @@ class NavigationBarApps extends LinearLayout { if (data.getItemCount() != 1) { return null; } Intent intent = data.getItemAt(0).getIntent(); ClipData.Item item = data.getItemAt(0); if (item == null) { return null; } Intent intent = item.getIntent(); if (intent == null) { return null; } long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, -1); // Validate the received user serial number. if (userSerialNumber == -1) { return null; } UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber); if (appUser == null) { appUser = new UserHandle(ActivityManager.getCurrentUser()); return null; } return new AppInfo(intent.getComponent(), appUser); ComponentName componentName = intent.getComponent(); if (componentName == null) { return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (sAppsModel.buildAppLaunchIntent(appInfo) == null) { return null; } return appInfo; } /** Updates the app at a given view index. */ Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java +48 −26 Original line number Diff line number Diff line Loading @@ -111,6 +111,20 @@ class NavigationBarAppsModel { ComponentName component = appInfo.getComponentName(); int appUserId = appInfo.getUser().getIdentifier(); if (mCurrentUserId != appUserId) { // Check if app user is a profile of current user and the app user is enabled. UserInfo appUserInfo = mUserManager.getUserInfo(appUserId); UserInfo currentUserInfo = mUserManager.getUserInfo(mCurrentUserId); if (appUserInfo == null || currentUserInfo == null || appUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || appUserInfo.profileGroupId != currentUserInfo.profileGroupId || !appUserInfo.isEnabled()) { Log.e(TAG, "User " + appUserId + " is is not a profile of the current user, or is disabled."); return null; } } // This code is based on LauncherAppsService.startActivityAsUser code. Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); Loading Loading @@ -165,7 +179,7 @@ class NavigationBarAppsModel { int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1); if (appCount >= 0) { loadAppsFromPrefs(); loadAppsFromPrefs(appCount); } else { // We switched to this user for the first time ever. This is a good opportunity to clean // prefs for users deleted in the past. Loading Loading @@ -258,37 +272,45 @@ class NavigationBarAppsModel { edit.apply(); } /** Loads the list of apps from SharedPreferences. */ private void loadAppsFromPrefs() { UserManager mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); boolean hadUnlauncheableApps = false; int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1); for (int i = 0; i < appCount; i++) { String prefValue = mPrefs.getString(prefNameForApp(i), null); /** Loads AppInfo from prefs. Returns null if something is wrong. */ private AppInfo loadAppFromPrefs(int index) { String prefValue = mPrefs.getString(prefNameForApp(index), null); if (prefValue == null) { Slog.w(TAG, "Couldn't find pref " + prefNameForApp(i)); // Couldn't find the saved state. Just skip this item. continue; Slog.w(TAG, "Couldn't find pref " + prefNameForApp(index)); return null; } ComponentName componentName = ComponentName.unflattenFromString(prefValue); long userSerialNumber = mPrefs.getLong(prefUserForApp(i), -1); if (componentName == null) { Slog.w(TAG, "Invalid component name " + prefValue); return null; } long userSerialNumber = mPrefs.getLong(prefUserForApp(index), -1); if (userSerialNumber == -1) { Slog.w(TAG, "Couldn't find pref " + prefUserForApp(i)); // Couldn't find the saved state. Just skip this item. continue; Slog.w(TAG, "Couldn't find pref " + prefUserForApp(index)); return null; } UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber); if (appUser == null) { Slog.w(TAG, "No user for serial " + userSerialNumber); return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (appUser != null && buildAppLaunchIntent(appInfo) != null) { if (buildAppLaunchIntent(appInfo) == null) { return null; } return appInfo; } /** Loads the list of apps from SharedPreferences. */ private void loadAppsFromPrefs(int appCount) { for (int i = 0; i < appCount; i++) { AppInfo appInfo = loadAppFromPrefs(i); if (appInfo != null) { mApps.add(appInfo); } else { hadUnlauncheableApps = true; } } if (hadUnlauncheableApps) savePrefs(); if (appCount != mApps.size()) savePrefs(); } /** Adds the first few apps from the owner profile. Used for demo purposes. */ Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java +26 −8 Original line number Diff line number Diff line Loading @@ -91,6 +91,16 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { when(mMockUserManager.getUserForSerialNumber(444L)).thenReturn(new UserHandle(4)); when(mMockUserManager.getUserForSerialNumber(555L)).thenReturn(new UserHandle(5)); UserInfo ui2 = new UserInfo(); ui2.profileGroupId = 999; UserInfo ui4 = new UserInfo(); ui4.profileGroupId = 999; UserInfo ui5 = new UserInfo(); ui5.profileGroupId = 999; when(mMockUserManager.getUserInfo(2)).thenReturn(ui2); when(mMockUserManager.getUserInfo(4)).thenReturn(ui4); when(mMockUserManager.getUserInfo(5)).thenReturn(ui5); mModel = new NavigationBarAppsModel(context) { @Override protected IPackageManager getPackageManager() { Loading Loading @@ -137,17 +147,22 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class))) .thenReturn(Arrays.asList(ri0, ri1)); mModel.setCurrentUser(3); // Unlauncheable (for various reasons) apps. assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package0", "class0"), new UserHandle(3)))); mModel.setCurrentUser(4); assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package1", "class1"), new UserHandle(4)))); mModel.setCurrentUser(5); assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package2", "class2"), new UserHandle(5)))); mModel.setCurrentUser(6); assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package3", "class3"), new UserHandle(6)))); // A launcheable app. mModel.setCurrentUser(7); Intent intent = mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package4", "class4"), new UserHandle(7))); assertNotNull(intent); Loading @@ -158,13 +173,11 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { /** Initializes the model from SharedPreferences for a few app activites. */ private void initializeModelFromPrefs() { // Assume several apps are stored. when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(3); when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0"); when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(-1L); when(mMockPrefs.getString("222|app_1", null)).thenReturn("package1/class1"); when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(444L); when(mMockPrefs.getString("222|app_2", null)).thenReturn("package2/class2"); when(mMockPrefs.getLong("222|app_user_2", -1)).thenReturn(555L); when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2); when(mMockPrefs.getString("222|app_0", null)).thenReturn("package1/class1"); when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(444L); when(mMockPrefs.getString("222|app_1", null)).thenReturn("package2/class2"); when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(555L); ActivityInfo mockActivityInfo = new ActivityInfo(); mockActivityInfo.exported = true; Loading Loading @@ -283,6 +296,11 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { assertEquals(1, mModel.getAppCount()); assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString()); assertEquals(new UserHandle(5), mModel.getApp(0).getUser()); InOrder order = inOrder(mMockEdit); order.verify(mMockEdit).putInt("222|app_count", 1); order.verify(mMockEdit).putString("222|app_0", "package0/class0"); order.verify(mMockEdit).putLong("222|app_user_0", 555L); order.verify(mMockEdit).apply(); verifyNoMoreInteractions(mMockEdit); } Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +19 −8 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ class NavigationBarApps extends LinearLayout { ComponentName appComponentName = appInfo.getComponentName(); if (!appComponentName.getPackageName().equals(packageName)) continue; if (sAppsModel.buildAppLaunchIntent(new AppInfo(appComponentName, user)) != null) { if (sAppsModel.buildAppLaunchIntent(appInfo) != null) { continue; } Loading Loading @@ -456,20 +456,31 @@ class NavigationBarApps extends LinearLayout { if (data.getItemCount() != 1) { return null; } Intent intent = data.getItemAt(0).getIntent(); ClipData.Item item = data.getItemAt(0); if (item == null) { return null; } Intent intent = item.getIntent(); if (intent == null) { return null; } long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, -1); // Validate the received user serial number. if (userSerialNumber == -1) { return null; } UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber); if (appUser == null) { appUser = new UserHandle(ActivityManager.getCurrentUser()); return null; } return new AppInfo(intent.getComponent(), appUser); ComponentName componentName = intent.getComponent(); if (componentName == null) { return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (sAppsModel.buildAppLaunchIntent(appInfo) == null) { return null; } return appInfo; } /** Updates the app at a given view index. */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java +48 −26 Original line number Diff line number Diff line Loading @@ -111,6 +111,20 @@ class NavigationBarAppsModel { ComponentName component = appInfo.getComponentName(); int appUserId = appInfo.getUser().getIdentifier(); if (mCurrentUserId != appUserId) { // Check if app user is a profile of current user and the app user is enabled. UserInfo appUserInfo = mUserManager.getUserInfo(appUserId); UserInfo currentUserInfo = mUserManager.getUserInfo(mCurrentUserId); if (appUserInfo == null || currentUserInfo == null || appUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID || appUserInfo.profileGroupId != currentUserInfo.profileGroupId || !appUserInfo.isEnabled()) { Log.e(TAG, "User " + appUserId + " is is not a profile of the current user, or is disabled."); return null; } } // This code is based on LauncherAppsService.startActivityAsUser code. Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); Loading Loading @@ -165,7 +179,7 @@ class NavigationBarAppsModel { int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1); if (appCount >= 0) { loadAppsFromPrefs(); loadAppsFromPrefs(appCount); } else { // We switched to this user for the first time ever. This is a good opportunity to clean // prefs for users deleted in the past. Loading Loading @@ -258,37 +272,45 @@ class NavigationBarAppsModel { edit.apply(); } /** Loads the list of apps from SharedPreferences. */ private void loadAppsFromPrefs() { UserManager mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); boolean hadUnlauncheableApps = false; int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1); for (int i = 0; i < appCount; i++) { String prefValue = mPrefs.getString(prefNameForApp(i), null); /** Loads AppInfo from prefs. Returns null if something is wrong. */ private AppInfo loadAppFromPrefs(int index) { String prefValue = mPrefs.getString(prefNameForApp(index), null); if (prefValue == null) { Slog.w(TAG, "Couldn't find pref " + prefNameForApp(i)); // Couldn't find the saved state. Just skip this item. continue; Slog.w(TAG, "Couldn't find pref " + prefNameForApp(index)); return null; } ComponentName componentName = ComponentName.unflattenFromString(prefValue); long userSerialNumber = mPrefs.getLong(prefUserForApp(i), -1); if (componentName == null) { Slog.w(TAG, "Invalid component name " + prefValue); return null; } long userSerialNumber = mPrefs.getLong(prefUserForApp(index), -1); if (userSerialNumber == -1) { Slog.w(TAG, "Couldn't find pref " + prefUserForApp(i)); // Couldn't find the saved state. Just skip this item. continue; Slog.w(TAG, "Couldn't find pref " + prefUserForApp(index)); return null; } UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber); if (appUser == null) { Slog.w(TAG, "No user for serial " + userSerialNumber); return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (appUser != null && buildAppLaunchIntent(appInfo) != null) { if (buildAppLaunchIntent(appInfo) == null) { return null; } return appInfo; } /** Loads the list of apps from SharedPreferences. */ private void loadAppsFromPrefs(int appCount) { for (int i = 0; i < appCount; i++) { AppInfo appInfo = loadAppFromPrefs(i); if (appInfo != null) { mApps.add(appInfo); } else { hadUnlauncheableApps = true; } } if (hadUnlauncheableApps) savePrefs(); if (appCount != mApps.size()) savePrefs(); } /** Adds the first few apps from the owner profile. Used for demo purposes. */ Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java +26 −8 Original line number Diff line number Diff line Loading @@ -91,6 +91,16 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { when(mMockUserManager.getUserForSerialNumber(444L)).thenReturn(new UserHandle(4)); when(mMockUserManager.getUserForSerialNumber(555L)).thenReturn(new UserHandle(5)); UserInfo ui2 = new UserInfo(); ui2.profileGroupId = 999; UserInfo ui4 = new UserInfo(); ui4.profileGroupId = 999; UserInfo ui5 = new UserInfo(); ui5.profileGroupId = 999; when(mMockUserManager.getUserInfo(2)).thenReturn(ui2); when(mMockUserManager.getUserInfo(4)).thenReturn(ui4); when(mMockUserManager.getUserInfo(5)).thenReturn(ui5); mModel = new NavigationBarAppsModel(context) { @Override protected IPackageManager getPackageManager() { Loading Loading @@ -137,17 +147,22 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class))) .thenReturn(Arrays.asList(ri0, ri1)); mModel.setCurrentUser(3); // Unlauncheable (for various reasons) apps. assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package0", "class0"), new UserHandle(3)))); mModel.setCurrentUser(4); assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package1", "class1"), new UserHandle(4)))); mModel.setCurrentUser(5); assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package2", "class2"), new UserHandle(5)))); mModel.setCurrentUser(6); assertEquals(null, mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package3", "class3"), new UserHandle(6)))); // A launcheable app. mModel.setCurrentUser(7); Intent intent = mModel.buildAppLaunchIntent( new AppInfo(new ComponentName("package4", "class4"), new UserHandle(7))); assertNotNull(intent); Loading @@ -158,13 +173,11 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { /** Initializes the model from SharedPreferences for a few app activites. */ private void initializeModelFromPrefs() { // Assume several apps are stored. when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(3); when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0"); when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(-1L); when(mMockPrefs.getString("222|app_1", null)).thenReturn("package1/class1"); when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(444L); when(mMockPrefs.getString("222|app_2", null)).thenReturn("package2/class2"); when(mMockPrefs.getLong("222|app_user_2", -1)).thenReturn(555L); when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2); when(mMockPrefs.getString("222|app_0", null)).thenReturn("package1/class1"); when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(444L); when(mMockPrefs.getString("222|app_1", null)).thenReturn("package2/class2"); when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(555L); ActivityInfo mockActivityInfo = new ActivityInfo(); mockActivityInfo.exported = true; Loading Loading @@ -283,6 +296,11 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { assertEquals(1, mModel.getAppCount()); assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString()); assertEquals(new UserHandle(5), mModel.getApp(0).getUser()); InOrder order = inOrder(mMockEdit); order.verify(mMockEdit).putInt("222|app_count", 1); order.verify(mMockEdit).putString("222|app_0", "package0/class0"); order.verify(mMockEdit).putLong("222|app_user_0", 555L); order.verify(mMockEdit).apply(); verifyNoMoreInteractions(mMockEdit); } Loading