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

Commit 53d79aa8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add tintable icon support" into oc-dr1-dev

parents 5af936f3 b10c6ffb
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -50,6 +50,12 @@ public class Tile implements Parcelable {
     */
    public Icon icon;

    /**
     * Whether the icon can be tinted. This should be set to true for monochrome (single-color)
     * icons that can be tinted to match the design.
     */
    public boolean isIconTintable;

    /**
     * Intent to launch when the preference is selected.
     */
@@ -126,6 +132,7 @@ public class Tile implements Parcelable {
        dest.writeBundle(metaData);
        dest.writeString(key);
        dest.writeParcelable(remoteViews, flags);
        dest.writeBoolean(isIconTintable);
    }

    public void readFromParcel(Parcel in) {
@@ -147,6 +154,7 @@ public class Tile implements Parcelable {
        metaData = in.readBundle();
        key = in.readString();
        remoteViews = in.readParcelable(RemoteViews.class.getClassLoader());
        isIconTintable = in.readBoolean();
    }

    Tile(Parcel in) {
+37 −12
Original line number Diff line number Diff line
@@ -133,15 +133,25 @@ 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.
     * to specify whether the icon is tintable. This should be a boolean value {@code true} or
     * {@code false}, set using {@code android:value}
     */
    @Deprecated
    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
    public static final String META_DATA_PREFERENCE_ICON_TINTABLE =
            "com.android.settings.icon_tintable";

    /**
     * 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.
     *
     * <p>Note: It is preferred to provide this value using {@code android:resource} with a string
     * resource for localization.
     */
    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";

    /**
     * @deprecated Use {@link #META_DATA_PREFERENCE_TITLE} with {@code android:resource}
     */
    @Deprecated
    public static final String META_DATA_PREFERENCE_TITLE_RES_ID =
            "com.android.settings.title.resid";

@@ -309,12 +319,13 @@ public class TileUtils {
            intent.setPackage(settingPkg);
        }
        getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
                usePriority, true);
                usePriority, true, true);
    }

    public static void getTilesForIntent(Context context, UserHandle user, Intent intent,
    public static void getTilesForIntent(
            Context context, UserHandle user, Intent intent,
            Map<Pair<String, String>, Tile> addedCache, String defaultCategory, List<Tile> outTiles,
            boolean usePriority, boolean checkCategory) {
            boolean usePriority, boolean checkCategory, boolean forceTintExternalIcon) {
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
                PackageManager.GET_META_DATA, user.getIdentifier());
@@ -350,7 +361,7 @@ public class TileUtils {
                tile.priority = usePriority ? resolved.priority : 0;
                tile.metaData = activityInfo.metaData;
                updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
                        pm, providerMap);
                        pm, providerMap, forceTintExternalIcon);
                if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);

                addedCache.put(key, tile);
@@ -366,25 +377,40 @@ public class TileUtils {

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

            // Get the activity's meta-data
            try {
                Resources res = pm.getResourcesForApplication(
                        applicationInfo.packageName);
                Resources res = pm.getResourcesForApplication(applicationInfo.packageName);
                Bundle metaData = activityInfo.metaData;

                if (forceTintExternalIcon
                        && !context.getPackageName().equals(applicationInfo.packageName)) {
                    isIconTintable = true;
                    forceTintIcon = true;
                }

                if (res != null && metaData != null) {
                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
                        icon = metaData.getInt(META_DATA_PREFERENCE_ICON);
                    }
                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON_TINTABLE)) {
                        if (forceTintIcon) {
                            Log.w(LOG_TAG, "Ignoring icon tintable for " + activityInfo);
                        } else {
                            isIconTintable =
                                    metaData.getBoolean(META_DATA_PREFERENCE_ICON_TINTABLE);
                        }
                    }
                    int resId = 0;
                    if (metaData.containsKey(META_DATA_PREFERENCE_TITLE_RES_ID)) {
                        resId = metaData.getInt(META_DATA_PREFERENCE_TITLE_RES_ID);
@@ -392,8 +418,6 @@ public class TileUtils {
                            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));
@@ -457,6 +481,7 @@ public class TileUtils {
                    activityInfo.name);
            // Suggest a key for this tile
            tile.key = keyHint;
            tile.isIconTintable = isIconTintable;
            tile.remoteViews = remoteViews;

            return true;
+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ public class SuggestionParser {
            intent.setPackage(category.pkg);
        }
        TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
                mAddCache, null, suggestions, true, false);
                mAddCache, null, suggestions, true, false, false);
        filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
        if (!category.multiple && suggestions.size() > (countBefore + 1)) {
            // If there are too many, remove them all and only re-add the one with the highest
+1 −1
Original line number Diff line number Diff line
@@ -19,5 +19,5 @@ package com.android.settingslib;
public class TestConfig {
    public static final int SDK_VERSION = 23;
    public static final String MANIFEST_PATH =
            "frameworks/base/packages/SettingsLib/robotests/AndroidManifest.xml";
            "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
}
+84 −29
Original line number Diff line number Diff line
@@ -16,6 +16,19 @@

package com.android.settingslib.drawer;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;

import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -50,8 +63,9 @@ import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.internal.ShadowExtractor;

import java.util.ArrayList;
@@ -59,20 +73,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
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,
@@ -100,8 +100,11 @@ public class TileUtilsTest {
        MockitoAnnotations.initMocks(this);
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
        mContentResolver = spy(RuntimeEnvironment.application.getContentResolver());
        when(mPackageManager.getApplicationInfo(eq("abc"), anyInt()))
                .thenReturn(application.getApplicationInfo());
        mContentResolver = spy(application.getContentResolver());
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        when(mContext.getPackageName()).thenReturn("com.android.settings");
    }

    @Test
@@ -118,7 +121,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).category).isEqualTo(testCategory);
@@ -139,7 +142,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).key).isEqualTo(keyHint);
@@ -159,7 +162,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.isEmpty()).isTrue();
    }
@@ -182,7 +185,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        SuggestionParser parser = new SuggestionParser(
@@ -255,7 +258,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).title).isEqualTo("my title");
@@ -279,10 +282,60 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).title).isEqualTo("my localized title");

        // Icon should be tintable because the tile is not from settings package, and
        // "forceTintExternalIcon" is set
        assertThat(outTiles.get(0).isIconTintable).isTrue();
    }

    @Test
    public void getTilesForIntent_shouldNotTintIconIfInSettingsPackage() {
        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, URI_GET_ICON,
                URI_GET_SUMMARY, null, 123);
        resolveInfo.activityInfo.packageName = "com.android.settings";
        resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
        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 */, true /* forceTintExternalIcon */);

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).isIconTintable).isFalse();
    }

    @Test
    public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
        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, URI_GET_ICON,
                URI_GET_SUMMARY, null, 123);
        resolveInfo.activityInfo.metaData
                .putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
        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 */, false /* forceTintExternalIcon */);

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).isIconTintable).isTrue();
    }

    @Test
@@ -301,7 +354,7 @@ public class TileUtilsTest {
        // Case 1: No provider associated with the uri specified.
        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                null /* defaultCategory */, outTiles, false /* usePriority */,
                false /* checkCategory */);
                false /* checkCategory */, true /* forceTintExternalIcon */);

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -319,7 +372,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -341,7 +394,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
    }
@@ -362,7 +415,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        Tile tile = outTiles.get(0);
@@ -399,7 +452,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        Tile tile = outTiles.get(0);
@@ -437,7 +490,7 @@ public class TileUtilsTest {

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

        assertThat(outTiles.size()).isEqualTo(1);
        Tile tile = outTiles.get(0);
@@ -484,7 +537,9 @@ public class TileUtilsTest {
        if (summaryUri != null) {
            info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri);
        }
        if (title != null) {
        if (titleResId != 0) {
            info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
        } else if (title != null) {
            info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
        }
        if (titleResId != 0) {