Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78c5e5dd authored by Jaewoong Jung's avatar Jaewoong Jung
Browse files

Allows to change summary text in a custom view tile.

Now it becomes possible to use META_DATA_PREFERENCE_SUMMARY_URI in
in conjunction with META_DATA_PREFERENCE_CUSTOM_VIEW.

Bug: 62384773
Test: make RunSettingsLibRoboTests -j40
Change-Id: I91401140b2ed0b12c26b91c8fb3d464179e75844
parent 1466c161
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -165,6 +165,9 @@ public class TileUtils {
     * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the
     * custom view which should be displayed for the preference. The custom view will be inflated
     * as a remote view.
     *
     * This also can be used with {@link META_DATA_PREFERENCE_SUMMARY_URI} above, by setting the id
     * of the summary TextView to '@android:id/summary'.
     */
    public static final String META_DATA_PREFERENCE_CUSTOM_VIEW =
            "com.android.settings.custom_view";
@@ -315,6 +318,7 @@ public class TileUtils {
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
                PackageManager.GET_META_DATA, user.getIdentifier());
        Map<String, IContentProvider> providerMap = new HashMap<>();
        for (ResolveInfo resolved : results) {
            if (!resolved.system) {
                // Do not allow any app to add to settings, only system ones.
@@ -346,7 +350,7 @@ public class TileUtils {
                tile.priority = usePriority ? resolved.priority : 0;
                tile.metaData = activityInfo.metaData;
                updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
                        pm);
                        pm, providerMap);
                if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);

                addedCache.put(key, tile);
@@ -361,14 +365,14 @@ public class TileUtils {
    }

    private static boolean updateTileData(Context context, Tile tile,
            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm) {
            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm,
            Map<String, IContentProvider> providerMap) {
        if (applicationInfo.isSystemApp()) {
            int icon = 0;
            Pair<String, Integer> iconFromUri = null;
            CharSequence title = null;
            String summary = null;
            String keyHint = null;
            Uri uri = null;
            RemoteViews remoteViews = null;

            // Get the activity's meta-data
@@ -414,6 +418,15 @@ public class TileUtils {
                    if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
                        int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
                        remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
                        if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
                            String uriString = metaData.getString(
                                    META_DATA_PREFERENCE_SUMMARY_URI);
                            String overrideSummary = getTextFromUri(context, uriString, providerMap,
                                    META_DATA_PREFERENCE_SUMMARY);
                            if (overrideSummary != null) {
                                remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
                            }
                        }
                    }
                }
            } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
+100 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.provider.Settings.Global;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Pair;
import android.widget.RemoteViews;

import com.android.settingslib.R;
import com.android.settingslib.TestConfig;
@@ -51,6 +52,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.internal.ShadowExtractor;

import java.util.ArrayList;
import java.util.Collections;
@@ -68,9 +70,13 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@Config(manifest = TestConfig.MANIFEST_PATH,
        sdk = TestConfig.SDK_VERSION,
        shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
public class TileUtilsTest {

    @Mock
@@ -364,6 +370,86 @@ public class TileUtilsTest {
        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
    }

    @Test
    public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
            throws RemoteException {
        Intent intent = new Intent();
        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
        List<Tile> outTiles = new ArrayList<>();
        List<ResolveInfo> info = new ArrayList<>();
        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
                null, URI_GET_SUMMARY);
        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
                R.layout.user_preference);
        info.add(resolveInfo);

        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
                .thenReturn(info);

        // Mock the content provider interaction.
        Bundle bundle = new Bundle();
        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
        when(mIContentProvider.call(anyString(),
                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
                any())).thenReturn(bundle);
        when(mContentResolver.acquireUnstableProvider(anyString()))
                .thenReturn(mIContentProvider);
        when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
                .thenReturn(mIContentProvider);

        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                null /* defaultCategory */, outTiles, false /* usePriority */,
                false /* checkCategory */);

        assertThat(outTiles.size()).isEqualTo(1);
        Tile tile = outTiles.get(0);
        assertThat(tile.remoteViews).isNotNull();
        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
        // Make sure the summary TextView got a new text string.
        TileUtilsShadowRemoteViews shadowRemoteViews =
                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
        assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
        assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
    }

    @Test
    public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
            throws RemoteException {
        Intent intent = new Intent();
        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
        List<Tile> outTiles = new ArrayList<>();
        List<ResolveInfo> info = new ArrayList<>();
        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
                null, URI_GET_SUMMARY);
        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
                R.layout.user_preference);
        info.add(resolveInfo);

        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
                .thenReturn(info);

        // Mock the content provider interaction.
        Bundle bundle = new Bundle();
        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
        when(mIContentProvider.call(anyString(),
                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
                any())).thenReturn(bundle);

        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                null /* defaultCategory */, outTiles, false /* usePriority */,
                false /* checkCategory */);

        assertThat(outTiles.size()).isEqualTo(1);
        Tile tile = outTiles.get(0);
        assertThat(tile.remoteViews).isNotNull();
        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
        // Make sure the summary TextView didn't get any text view updates.
        TileUtilsShadowRemoteViews shadowRemoteViews =
                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
        assertThat(shadowRemoteViews.overrideViewId).isNull();
        assertThat(shadowRemoteViews.overrideText).isNull();
    }

    public static ResolveInfo newInfo(boolean systemApp, String category) {
        return newInfo(systemApp, category, null);
    }
@@ -423,4 +509,17 @@ public class TileUtilsTest {
            info.activityInfo.metaData.putString(key, value);
        }
    }

    @Implements(RemoteViews.class)
    public static class TileUtilsShadowRemoteViews {

        private Integer overrideViewId;
        private CharSequence overrideText;

        @Implementation
        public void setTextViewText(int viewId, CharSequence text) {
            overrideViewId = viewId;
            overrideText = text;
        }
    }
}