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

Commit 83dde97b authored by Fan Zhang's avatar Fan Zhang
Browse files

Add activityInfo and getIcon() method in Tile class.

Moved loading icon logic from TileUtils into Tile#getIcon().

TileUtils only load things once and cache forever but getIcon()
loads a fresh icon every time to avoid any caching issue.

Bug: 77600770
Test: robotests
Change-Id: I706225e382ebd5b72e91edef43bfc7427fa64590
parent bf2f826a
Loading
Loading
Loading
Loading
+41 −20
Original line number Diff line number Diff line
@@ -17,17 +17,19 @@
package com.android.settingslib.drawer;

import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.TextUtils;
import android.widget.RemoteViews;

import java.util.ArrayList;

@@ -36,24 +38,23 @@ import java.util.ArrayList;
 */
public class Tile implements Parcelable {

    private static final String TAG = "Tile";
    private ActivityInfo mActivityInfo;

    /**
     * Title of the tile that is shown to the user.
     *
     * @attr ref android.R.styleable#PreferenceHeader_title
     */
    public CharSequence title;

    /**
     * Optional summary describing what this tile controls.
     *
     * @attr ref android.R.styleable#PreferenceHeader_summary
     */
    public CharSequence summary;

    /**
     * Optional icon to show for this tile.
     * @attr ref android.R.styleable#PreferenceHeader_icon
     */
    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.
@@ -95,8 +96,8 @@ public class Tile implements Parcelable {
     */
    public String key;

    public Tile() {
        // Empty
    public Tile(ActivityInfo activityInfo) {
        mActivityInfo = activityInfo;
    }

    @Override
@@ -106,14 +107,9 @@ public class Tile implements Parcelable {

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(mActivityInfo, flags);
        TextUtils.writeToParcel(title, dest, flags);
        TextUtils.writeToParcel(summary, dest, flags);
        if (icon != null) {
            dest.writeByte((byte) 1);
            icon.writeToParcel(dest, flags);
        } else {
            dest.writeByte((byte) 0);
        }
        if (intent != null) {
            dest.writeByte((byte) 1);
            intent.writeToParcel(dest, flags);
@@ -133,12 +129,36 @@ public class Tile implements Parcelable {
        dest.writeBoolean(isIconTintable);
    }

    /**
     * Optional icon to show for this tile.
     *
     * @attr ref android.R.styleable#PreferenceHeader_icon
     */
    public Icon getIcon() {
        if (mActivityInfo == null || metaData == null) {
            return null;
        }
        int iconResId = metaData.getInt(META_DATA_PREFERENCE_ICON);
        // Set the icon
        if (iconResId == 0) {
            // Only fallback to activityinfo.icon if metadata does not contain ICON_URI.
            // ICON_URI should be loaded in app UI when need the icon object. Handling IPC at this
            // level is too complex because we don't have a strong threading contract for this class
            if (!metaData.containsKey(META_DATA_PREFERENCE_ICON_URI)) {
                iconResId = mActivityInfo.icon;
            }
        }
        if (iconResId != 0) {
            return Icon.createWithResource(mActivityInfo.packageName, iconResId);
        } else {
            return null;
        }
    }

    public void readFromParcel(Parcel in) {
        mActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
        title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
        summary = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
        if (in.readByte() != 0) {
            icon = Icon.CREATOR.createFromParcel(in);
        }
        if (in.readByte() != 0) {
            intent = Intent.CREATOR.createFromParcel(in);
        }
@@ -162,6 +182,7 @@ public class Tile implements Parcelable {
        public Tile createFromParcel(Parcel source) {
            return new Tile(source);
        }

        public Tile[] newArray(int size) {
            return new Tile[size];
        }
+1 −18
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
@@ -303,7 +302,7 @@ public class TileUtils {
            Pair<String, String> key = new Pair<>(activityInfo.packageName, activityInfo.name);
            Tile tile = addedCache.get(key);
            if (tile == null) {
                tile = new Tile();
                tile = new Tile(activityInfo);
                tile.intent = new Intent().setClassName(
                        activityInfo.packageName, activityInfo.name);
                tile.category = categoryKey;
@@ -329,7 +328,6 @@ public class TileUtils {
            boolean forceTintExternalIcon) {
        if (applicationInfo.isSystemApp()) {
            boolean forceTintIcon = false;
            int icon = 0;
            CharSequence title = null;
            String summary = null;
            String keyHint = null;
@@ -347,9 +345,6 @@ public class TileUtils {
                }

                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);
@@ -390,18 +385,6 @@ public class TileUtils {
                title = activityInfo.loadLabel(pm).toString();
            }

            // Set the icon
            if (icon == 0) {
                // Only fallback to activityinfo.icon if metadata does not contain ICON_URI.
                // ICON_URI should be loaded in app UI when need the icon object.
                if (!tile.metaData.containsKey(META_DATA_PREFERENCE_ICON_URI)) {
                    icon = activityInfo.icon;
                }
            }
            if (icon != 0) {
                tile.icon = Icon.createWithResource(activityInfo.packageName, icon);
            }

            // Set title and summary for the preference
            tile.title = title;
            tile.summary = summary;
+10 −8
Original line number Diff line number Diff line
@@ -16,8 +16,16 @@

package com.android.settingslib.drawer;

import static junit.framework.Assert.assertEquals;

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
@@ -30,12 +38,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class ProfileSelectDialogTest {
@@ -58,7 +60,7 @@ public class ProfileSelectDialogTest {

    @Test
    public void testUpdateUserHandlesIfNeeded_Normal() {
        final Tile tile = new Tile();
        final Tile tile = new Tile(new ActivityInfo());
        tile.intent = new Intent();
        tile.userHandle.add(NORMAL_USER);

@@ -71,7 +73,7 @@ public class ProfileSelectDialogTest {

    @Test
    public void testUpdateUserHandlesIfNeeded_Remove() {
        final Tile tile = new Tile();
        final Tile tile = new Tile(new ActivityInfo());
        tile.intent = new Intent();
        tile.userHandle.add(REMOVED_USER);
        tile.userHandle.add(NORMAL_USER);
+41 −1
Original line number Diff line number Diff line
package com.android.settingslib.drawer;

import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;

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

import android.content.pm.ActivityInfo;
import android.os.Bundle;

import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;


@RunWith(SettingsLibRobolectricTestRunner.class)
public class TileTest {

    private ActivityInfo mActivityInfo;
    private Tile mTile;

    @Before
    public void setUp() {
        mTile = new Tile();
        mActivityInfo = new ActivityInfo();
        mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName();
        mActivityInfo.icon = R.drawable.ic_plus;
        mTile = new Tile(mActivityInfo);
        mTile.metaData = new Bundle();
    }

@@ -47,4 +57,34 @@ public class TileTest {
        mTile.metaData = null;
        assertThat(mTile.isPrimaryProfileOnly()).isFalse();
    }

    @Test
    public void getIcon_noActivityOrMetadata_returnNull() {
        final Tile tile1 = new Tile((ActivityInfo) null);
        assertThat(tile1.getIcon()).isNull();

        final Tile tile2 = new Tile(new ActivityInfo());
        assertThat(tile2.getIcon()).isNull();
    }

    @Test
    public void getIcon_providedByUri_returnNull() {
        mTile.metaData.putString(META_DATA_PREFERENCE_ICON_URI, "content://foobar/icon");

        assertThat(mTile.getIcon()).isNull();
    }

    @Test
    public void getIcon_hasIconMetadata_returnIcon() {
        mTile.metaData.putInt(META_DATA_PREFERENCE_ICON, R.drawable.ic_info);

        assertThat(mTile.getIcon().getResId()).isEqualTo(R.drawable.ic_info);
    }

    @Test
    public void getIcon_noIconMetadata_returnActivityIcon() {
        mTile.metaData.putInt(META_DATA_PREFERENCE_ICON, 0);

        assertThat(mTile.getIcon().getResId()).isEqualTo(mActivityInfo.icon);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ public class TileUtilsTest {
                false /* checkCategory */, true /* forceTintExternalIcon */);

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
        assertThat(outTiles.get(0).getIcon().getResId()).isEqualTo(314159);
        assertThat(outTiles.get(0).summary).isEqualTo("static-summary");

        // Case 2: Empty bundle.
@@ -332,7 +332,7 @@ public class TileUtilsTest {
                false /* checkCategory */, true /* forceTintExternalIcon */);

        assertThat(outTiles.size()).isEqualTo(1);
        assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
        assertThat(outTiles.get(0).getIcon().getResId()).isEqualTo(314159);
        assertThat(outTiles.get(0).summary).isEqualTo("static-summary");
    }

Loading