From 4c978a302afb0e3b416319b3cd963a6e7ccc379d Mon Sep 17 00:00:00 2001 From: William Luh Date: Fri, 31 Mar 2017 15:08:16 -0700 Subject: [PATCH] Fix injected settings titles not matching a locale change. The injected tiles code currently treats the string metadata value for the title key in the Activity's manifest as the title itself. When the language on the device is changed the title remains in the previous language until a reboot. This CL will make injected tiles attempt to treat the string metadata value as a resource variable to get the integer res id and then properly load the localized title using the res id. To be backwards compatible, if the res id is 0, we treat the string metadata value as the title itself (current behavior). Bug:36470694 Test: make RunSettingsLibRoboTests Change-Id: I3963534a3a3a27d0455c4ed1ad4fa574b03d67fc --- .../android/settingslib/drawer/TileUtils.java | 19 +++++- .../settingslib/drawer/TileUtilsTest.java | 60 ++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java index f31c09b104fdc..6bcf256a80331 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java @@ -135,8 +135,16 @@ public class TileUtils { * Name of the meta-data item that should be set in the AndroidManifest.xml * to specify the title that should be displayed for the preference. */ + @Deprecated public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title"; + /** + * Name of the meta-data item that should be set in the AndroidManifest.xml + * to specify the title that should be displayed for the preference. + */ + public static final String META_DATA_PREFERENCE_TITLE_RES_ID = + "com.android.settings.title.resid"; + /** * Name of the meta-data item that should be set in the AndroidManifest.xml * to specify the summary text that should be displayed for the preference. @@ -364,7 +372,16 @@ public class TileUtils { if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) { icon = metaData.getInt(META_DATA_PREFERENCE_ICON); } - if (metaData.containsKey(META_DATA_PREFERENCE_TITLE)) { + int resId = 0; + if (metaData.containsKey(META_DATA_PREFERENCE_TITLE_RES_ID)) { + resId = metaData.getInt(META_DATA_PREFERENCE_TITLE_RES_ID); + if (resId != 0) { + title = res.getString(resId); + } + } + // Fallback to legacy title extraction if we couldn't get the title through + // res id. + if ((resId == 0) && metaData.containsKey(META_DATA_PREFERENCE_TITLE)) { if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) { title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE)); } else { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java index 2d3c4a786f5c8..5310b7a604b0a 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java @@ -230,6 +230,51 @@ public class TileUtilsTest { .isEqualTo(TileUtils.SETTING_PKG); } + @Test + public void getTilesForIntent_shouldReadMetadataTitleAsString() throws RemoteException { + Intent intent = new Intent(); + Map, Tile> addedCache = new ArrayMap<>(); + List outTiles = new ArrayList<>(); + List info = new ArrayList<>(); + ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON, + URI_GET_SUMMARY, "my title", 0); + info.add(resolveInfo); + + when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt())) + .thenReturn(info); + + TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache, + null /* defaultCategory */, outTiles, false /* usePriority */, + false /* checkCategory */); + + assertThat(outTiles.size()).isEqualTo(1); + assertThat(outTiles.get(0).title).isEqualTo("my title"); + } + + @Test + public void getTilesForIntent_shouldReadMetadataTitleFromResource() throws RemoteException { + Intent intent = new Intent(); + Map, Tile> addedCache = new ArrayMap<>(); + List outTiles = new ArrayList<>(); + List info = new ArrayList<>(); + ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON, + URI_GET_SUMMARY, null, 123); + info.add(resolveInfo); + + when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt())) + .thenReturn(info); + + when(mResources.getString(eq(123))) + .thenReturn("my localized title"); + + TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache, + null /* defaultCategory */, outTiles, false /* usePriority */, + false /* checkCategory */); + + assertThat(outTiles.size()).isEqualTo(1); + assertThat(outTiles.get(0).title).isEqualTo("my localized title"); + } + @Test public void getTilesForIntent_shouldNotProcessInvalidUriContentSystemApp() throws RemoteException { @@ -298,7 +343,13 @@ public class TileUtilsTest { } private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint, - String iconUri, String summaryUri) { + String iconUri, String summaryUri) { + return newInfo(systemApp, category, keyHint, iconUri, summaryUri, null, 0); + } + + private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint, + String iconUri, String summaryUri, String title, int titleResId) { + ResolveInfo info = new ResolveInfo(); info.system = systemApp; info.activityInfo = new ActivityInfo(); @@ -317,6 +368,13 @@ public class TileUtilsTest { if (summaryUri != null) { info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri); } + if (title != null) { + info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title); + } + if (titleResId != 0) { + info.activityInfo.metaData.putInt( + TileUtils.META_DATA_PREFERENCE_TITLE_RES_ID, titleResId); + } info.activityInfo.applicationInfo = new ApplicationInfo(); if (systemApp) { info.activityInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;