Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +20 −28 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.PixelFormat; Loading Loading @@ -247,7 +246,7 @@ class NavigationBarApps extends LinearLayout ComponentName appComponentName = appInfo.getComponentName(); if (!appComponentName.getPackageName().equals(packageName)) continue; if (sAppsModel.buildAppLaunchIntent(appInfo) != null) { if (sAppsModel.resolveApp(appInfo) != null) { continue; } Loading Loading @@ -309,15 +308,9 @@ class NavigationBarApps extends LinearLayout } private void addAppButton(AppButtonData appButtonData) { ImageView button = createAppButton(appButtonData); ImageView button = createAppButton(); updateApp(button, appButtonData); addView(button); AppInfo app = appButtonData.appInfo; CharSequence appLabel = getAppLabel(mPackageManager, app.getComponentName()); button.setContentDescription(appLabel); // Load the icon asynchronously. new GetActivityIconTask(mPackageManager, button).execute(appButtonData); } private List<AppInfo> getPinnedApps() { Loading Loading @@ -359,7 +352,7 @@ class NavigationBarApps extends LinearLayout /** * Creates a new ImageView for an app, inflated from R.layout.navigation_bar_app_item. */ private ImageView createAppButton(AppButtonData appButtonData) { private ImageView createAppButton() { ImageView button = (ImageView) mLayoutInflater.inflate( R.layout.navigation_bar_app_item, this, false /* attachToRoot */); button.setOnHoverListener(new AppHoverListener()); Loading @@ -368,7 +361,6 @@ class NavigationBarApps extends LinearLayout // TODO: Ripple effect. Use either KeyButtonRipple or the default ripple background. button.setOnLongClickListener(new AppLongClickListener()); button.setOnDragListener(new AppIconDragListener()); button.setTag(appButtonData); return button; } Loading @@ -387,17 +379,12 @@ class NavigationBarApps extends LinearLayout * TODO: Cache the labels, perhaps in an LruCache. */ @Nullable static CharSequence getAppLabel(PackageManager packageManager, ComponentName activityName) { String packageName = activityName.getPackageName(); ApplicationInfo info; try { info = packageManager.getApplicationInfo(packageName, 0x0 /* flags */); } catch (PackageManager.NameNotFoundException e) { Slog.w(TAG, "Package not found " + packageName); return null; } return packageManager.getApplicationLabel(info); private CharSequence getAppLabel(AppInfo appInfo) { NavigationBarAppsModel.ResolvedApp resolvedApp = sAppsModel.resolveApp(appInfo); if (resolvedApp == null) return null; CharSequence unbadgedLabel = resolvedApp.ri.loadLabel(mPackageManager); return mUserManager.getBadgedLabelForUser(unbadgedLabel, appInfo.getUser()); } /** Helper function to start dragging an app icon (either pinned or recent). */ Loading Loading @@ -484,7 +471,7 @@ class NavigationBarApps extends LinearLayout * Creates a blank icon-sized View to create an empty space during a drag. */ private ImageView createPlaceholderDragView(int index) { ImageView button = createAppButton(null); ImageView button = createAppButton(); addView(button, index); return button; } Loading Loading @@ -637,7 +624,7 @@ class NavigationBarApps extends LinearLayout return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (sAppsModel.buildAppLaunchIntent(appInfo) == null) { if (sAppsModel.resolveApp(appInfo) == null) { return null; } return appInfo; Loading @@ -645,6 +632,9 @@ class NavigationBarApps extends LinearLayout /** Updates the app at a given view index. */ private void updateApp(ImageView button, AppButtonData appButtonData) { CharSequence appLabel = getAppLabel(appButtonData.appInfo); button.setContentDescription(appLabel); button.setTag(appButtonData); new GetActivityIconTask(mPackageManager, button).execute(appButtonData); } Loading Loading @@ -829,13 +819,15 @@ class NavigationBarApps extends LinearLayout */ private class AppClickListener implements View.OnClickListener { private void launchApp(AppInfo appInfo, View anchor) { Intent launchIntent = sAppsModel.buildAppLaunchIntent(appInfo); if (launchIntent == null) { NavigationBarAppsModel.ResolvedApp resolvedApp = sAppsModel.resolveApp(appInfo); if (resolvedApp == null) { Toast.makeText( getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show(); return; } Intent launchIntent = resolvedApp.launchIntent; // Play a scale-up animation while launching the activity. // TODO: Consider playing a different animation, or no animation, if the activity is // already open in a visible window. In that case we should move the task to front Loading Loading @@ -1078,7 +1070,7 @@ class NavigationBarApps extends LinearLayout UserHandle taskUser = new UserHandle(task.userId); AppInfo appInfo = new AppInfo(componentName, taskUser); if (sAppsModel.buildAppLaunchIntent(appInfo) == null) { if (sAppsModel.resolveApp(appInfo) == null) { // If task's activity is not launcheable, fall back to a launch component of the // task's package. ComponentName component = getLaunchComponentForPackage( Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java +14 −5 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ class NavigationBarAppsModel { void onPinnedAppsChanged(); } public class ResolvedApp { Intent launchIntent; ResolveInfo ri; } private final static String TAG = "NavigationBarAppsModel"; // Default number of apps to load initially. Loading Loading @@ -112,8 +117,8 @@ class NavigationBarAppsModel { return AppGlobals.getPackageManager(); } // Returns a launch intent for a given app info, or null if the app info is unlauncheable. public Intent buildAppLaunchIntent(AppInfo appInfo) { // Returns a resolved app info for a given app info, or null if the app info is unlauncheable. public ResolvedApp resolveApp(AppInfo appInfo) { ComponentName component = appInfo.getComponentName(); int appUserId = appInfo.getUser().getIdentifier(); Loading Loading @@ -160,13 +165,17 @@ class NavigationBarAppsModel { 0 /* flags */, appUserId); final int size = apps.size(); for (int i = 0; i < size; ++i) { ActivityInfo activityInfo = apps.get(i).activityInfo; ResolveInfo ri = apps.get(i); ActivityInfo activityInfo = ri.activityInfo; if (activityInfo.packageName.equals(component.getPackageName()) && activityInfo.name.equals(component.getClassName())) { // Found an activity with category launcher that matches // this component so ok to launch. launchIntent.setComponent(component); return launchIntent; ResolvedApp resolvedApp = new ResolvedApp(); resolvedApp.launchIntent = launchIntent; resolvedApp.ri = ri; return resolvedApp; } } Loading Loading @@ -300,7 +309,7 @@ class NavigationBarAppsModel { return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (buildAppLaunchIntent(appInfo) == null) { if (resolveApp(appInfo) == null) { return null; } return appInfo; Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java +10 −9 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.List; import java.util.Map; /** Tests for the data model for the navigation bar app icons. */ Loading Loading @@ -109,8 +108,8 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { }; } /** Tests buildAppLaunchIntent(). */ public void testBuildAppLaunchIntent() { /** Tests resolveApp(). */ public void testResolveApp() { ActivityInfo mockNonExportedActivityInfo = new ActivityInfo(); mockNonExportedActivityInfo.exported = false; ActivityInfo mockExportedActivityInfo = new ActivityInfo(); Loading Loading @@ -149,25 +148,27 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { mModel.setCurrentUser(3); // Unlauncheable (for various reasons) apps. assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package0", "class0"), new UserHandle(3)))); mModel.setCurrentUser(4); assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package1", "class1"), new UserHandle(4)))); mModel.setCurrentUser(5); assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package2", "class2"), new UserHandle(5)))); mModel.setCurrentUser(6); assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package3", "class3"), new UserHandle(6)))); // A launcheable app. mModel.setCurrentUser(7); Intent intent = mModel.buildAppLaunchIntent( NavigationBarAppsModel.ResolvedApp resolvedApp = mModel.resolveApp( new AppInfo(new ComponentName("package4", "class4"), new UserHandle(7))); assertNotNull(intent); assertNotNull(resolvedApp); Intent intent = resolvedApp.launchIntent; assertEquals(new ComponentName("package4", "class4"), intent.getComponent()); assertEquals("package4", intent.getPackage()); assertEquals(ri1, resolvedApp.ri); } /** Initializes the model from SharedPreferences for a few app activites. */ Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java +20 −28 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.PixelFormat; Loading Loading @@ -247,7 +246,7 @@ class NavigationBarApps extends LinearLayout ComponentName appComponentName = appInfo.getComponentName(); if (!appComponentName.getPackageName().equals(packageName)) continue; if (sAppsModel.buildAppLaunchIntent(appInfo) != null) { if (sAppsModel.resolveApp(appInfo) != null) { continue; } Loading Loading @@ -309,15 +308,9 @@ class NavigationBarApps extends LinearLayout } private void addAppButton(AppButtonData appButtonData) { ImageView button = createAppButton(appButtonData); ImageView button = createAppButton(); updateApp(button, appButtonData); addView(button); AppInfo app = appButtonData.appInfo; CharSequence appLabel = getAppLabel(mPackageManager, app.getComponentName()); button.setContentDescription(appLabel); // Load the icon asynchronously. new GetActivityIconTask(mPackageManager, button).execute(appButtonData); } private List<AppInfo> getPinnedApps() { Loading Loading @@ -359,7 +352,7 @@ class NavigationBarApps extends LinearLayout /** * Creates a new ImageView for an app, inflated from R.layout.navigation_bar_app_item. */ private ImageView createAppButton(AppButtonData appButtonData) { private ImageView createAppButton() { ImageView button = (ImageView) mLayoutInflater.inflate( R.layout.navigation_bar_app_item, this, false /* attachToRoot */); button.setOnHoverListener(new AppHoverListener()); Loading @@ -368,7 +361,6 @@ class NavigationBarApps extends LinearLayout // TODO: Ripple effect. Use either KeyButtonRipple or the default ripple background. button.setOnLongClickListener(new AppLongClickListener()); button.setOnDragListener(new AppIconDragListener()); button.setTag(appButtonData); return button; } Loading @@ -387,17 +379,12 @@ class NavigationBarApps extends LinearLayout * TODO: Cache the labels, perhaps in an LruCache. */ @Nullable static CharSequence getAppLabel(PackageManager packageManager, ComponentName activityName) { String packageName = activityName.getPackageName(); ApplicationInfo info; try { info = packageManager.getApplicationInfo(packageName, 0x0 /* flags */); } catch (PackageManager.NameNotFoundException e) { Slog.w(TAG, "Package not found " + packageName); return null; } return packageManager.getApplicationLabel(info); private CharSequence getAppLabel(AppInfo appInfo) { NavigationBarAppsModel.ResolvedApp resolvedApp = sAppsModel.resolveApp(appInfo); if (resolvedApp == null) return null; CharSequence unbadgedLabel = resolvedApp.ri.loadLabel(mPackageManager); return mUserManager.getBadgedLabelForUser(unbadgedLabel, appInfo.getUser()); } /** Helper function to start dragging an app icon (either pinned or recent). */ Loading Loading @@ -484,7 +471,7 @@ class NavigationBarApps extends LinearLayout * Creates a blank icon-sized View to create an empty space during a drag. */ private ImageView createPlaceholderDragView(int index) { ImageView button = createAppButton(null); ImageView button = createAppButton(); addView(button, index); return button; } Loading Loading @@ -637,7 +624,7 @@ class NavigationBarApps extends LinearLayout return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (sAppsModel.buildAppLaunchIntent(appInfo) == null) { if (sAppsModel.resolveApp(appInfo) == null) { return null; } return appInfo; Loading @@ -645,6 +632,9 @@ class NavigationBarApps extends LinearLayout /** Updates the app at a given view index. */ private void updateApp(ImageView button, AppButtonData appButtonData) { CharSequence appLabel = getAppLabel(appButtonData.appInfo); button.setContentDescription(appLabel); button.setTag(appButtonData); new GetActivityIconTask(mPackageManager, button).execute(appButtonData); } Loading Loading @@ -829,13 +819,15 @@ class NavigationBarApps extends LinearLayout */ private class AppClickListener implements View.OnClickListener { private void launchApp(AppInfo appInfo, View anchor) { Intent launchIntent = sAppsModel.buildAppLaunchIntent(appInfo); if (launchIntent == null) { NavigationBarAppsModel.ResolvedApp resolvedApp = sAppsModel.resolveApp(appInfo); if (resolvedApp == null) { Toast.makeText( getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show(); return; } Intent launchIntent = resolvedApp.launchIntent; // Play a scale-up animation while launching the activity. // TODO: Consider playing a different animation, or no animation, if the activity is // already open in a visible window. In that case we should move the task to front Loading Loading @@ -1078,7 +1070,7 @@ class NavigationBarApps extends LinearLayout UserHandle taskUser = new UserHandle(task.userId); AppInfo appInfo = new AppInfo(componentName, taskUser); if (sAppsModel.buildAppLaunchIntent(appInfo) == null) { if (sAppsModel.resolveApp(appInfo) == null) { // If task's activity is not launcheable, fall back to a launch component of the // task's package. ComponentName component = getLaunchComponentForPackage( Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java +14 −5 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ class NavigationBarAppsModel { void onPinnedAppsChanged(); } public class ResolvedApp { Intent launchIntent; ResolveInfo ri; } private final static String TAG = "NavigationBarAppsModel"; // Default number of apps to load initially. Loading Loading @@ -112,8 +117,8 @@ class NavigationBarAppsModel { return AppGlobals.getPackageManager(); } // Returns a launch intent for a given app info, or null if the app info is unlauncheable. public Intent buildAppLaunchIntent(AppInfo appInfo) { // Returns a resolved app info for a given app info, or null if the app info is unlauncheable. public ResolvedApp resolveApp(AppInfo appInfo) { ComponentName component = appInfo.getComponentName(); int appUserId = appInfo.getUser().getIdentifier(); Loading Loading @@ -160,13 +165,17 @@ class NavigationBarAppsModel { 0 /* flags */, appUserId); final int size = apps.size(); for (int i = 0; i < size; ++i) { ActivityInfo activityInfo = apps.get(i).activityInfo; ResolveInfo ri = apps.get(i); ActivityInfo activityInfo = ri.activityInfo; if (activityInfo.packageName.equals(component.getPackageName()) && activityInfo.name.equals(component.getClassName())) { // Found an activity with category launcher that matches // this component so ok to launch. launchIntent.setComponent(component); return launchIntent; ResolvedApp resolvedApp = new ResolvedApp(); resolvedApp.launchIntent = launchIntent; resolvedApp.ri = ri; return resolvedApp; } } Loading Loading @@ -300,7 +309,7 @@ class NavigationBarAppsModel { return null; } AppInfo appInfo = new AppInfo(componentName, appUser); if (buildAppLaunchIntent(appInfo) == null) { if (resolveApp(appInfo) == null) { return null; } return appInfo; Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java +10 −9 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.List; import java.util.Map; /** Tests for the data model for the navigation bar app icons. */ Loading Loading @@ -109,8 +108,8 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { }; } /** Tests buildAppLaunchIntent(). */ public void testBuildAppLaunchIntent() { /** Tests resolveApp(). */ public void testResolveApp() { ActivityInfo mockNonExportedActivityInfo = new ActivityInfo(); mockNonExportedActivityInfo.exported = false; ActivityInfo mockExportedActivityInfo = new ActivityInfo(); Loading Loading @@ -149,25 +148,27 @@ public class NavigationBarAppsModelTest extends AndroidTestCase { mModel.setCurrentUser(3); // Unlauncheable (for various reasons) apps. assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package0", "class0"), new UserHandle(3)))); mModel.setCurrentUser(4); assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package1", "class1"), new UserHandle(4)))); mModel.setCurrentUser(5); assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package2", "class2"), new UserHandle(5)))); mModel.setCurrentUser(6); assertEquals(null, mModel.buildAppLaunchIntent( assertEquals(null, mModel.resolveApp( new AppInfo(new ComponentName("package3", "class3"), new UserHandle(6)))); // A launcheable app. mModel.setCurrentUser(7); Intent intent = mModel.buildAppLaunchIntent( NavigationBarAppsModel.ResolvedApp resolvedApp = mModel.resolveApp( new AppInfo(new ComponentName("package4", "class4"), new UserHandle(7))); assertNotNull(intent); assertNotNull(resolvedApp); Intent intent = resolvedApp.launchIntent; assertEquals(new ComponentName("package4", "class4"), intent.getComponent()); assertEquals("package4", intent.getPackage()); assertEquals(ri1, resolvedApp.ri); } /** Initializes the model from SharedPreferences for a few app activites. */ Loading