Merge "Fix accessibility labels for app icons."
This commit is contained in:
committed by
Android (Google) Code Review
commit
21c5f536eb
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
@@ -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());
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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). */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
@@ -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();
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user