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

Commit 8f942a49 authored by Fan Zhang's avatar Fan Zhang
Browse files

Refreshes injected tile metadata when app is updated.

Otherwise the metadata in Tile is stale and when we use it to load stuff
from PackageManager it will just return nonsense.

Fixes: 123349246
Test: robotests
Change-Id: I02b6987401718db5ab777835885eb02def3d3fa5
parent 32a38edc
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -58,6 +60,8 @@ public class Tile implements Parcelable {
     */
    public ArrayList<UserHandle> userHandle = new ArrayList<>();

    @VisibleForTesting
    long mLastUpdateTime;
    private final String mActivityPackage;
    private final String mActivityName;
    private final Intent mIntent;
@@ -157,6 +161,7 @@ public class Tile implements Parcelable {
     */
    public CharSequence getTitle(Context context) {
        CharSequence title = null;
        ensureMetadataNotStale(context);
        final PackageManager packageManager = context.getPackageManager();
        if (mMetaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
            if (mMetaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
@@ -207,6 +212,7 @@ public class Tile implements Parcelable {
        if (mSummaryOverride != null) {
            return mSummaryOverride;
        }
        ensureMetadataNotStale(context);
        CharSequence summary = null;
        final PackageManager packageManager = context.getPackageManager();
        if (mMetaData != null) {
@@ -248,6 +254,7 @@ public class Tile implements Parcelable {
        if (!hasKey()) {
            return null;
        }
        ensureMetadataNotStale(context);
        if (mMetaData.get(META_DATA_PREFERENCE_KEYHINT) instanceof Integer) {
            return context.getResources().getString(mMetaData.getInt(META_DATA_PREFERENCE_KEYHINT));
        } else {
@@ -268,7 +275,7 @@ public class Tile implements Parcelable {
        if (context == null || mMetaData == null) {
            return null;
        }

        ensureMetadataNotStale(context);
        int iconResId = mMetaData.getInt(META_DATA_PREFERENCE_ICON);
        // Set the icon
        if (iconResId == 0) {
@@ -294,6 +301,7 @@ public class Tile implements Parcelable {
                && mMetaData.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) {
            return mMetaData.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE);
        }
        ensureMetadataNotStale(context);
        final String pkgName = context.getPackageName();
        // If this drawable is coming from outside Settings, tint it to match the color.
        final ActivityInfo activityInfo = getActivityInfo(context);
@@ -301,6 +309,28 @@ public class Tile implements Parcelable {
                && !TextUtils.equals(pkgName, activityInfo.packageName);
    }

    /**
     * Ensures metadata is not stale for this tile.
     */
    private void ensureMetadataNotStale(Context context) {
        final PackageManager pm = context.getApplicationContext().getPackageManager();

        try {
            final long lastUpdateTime = pm.getPackageInfo(mActivityPackage,
                    PackageManager.GET_META_DATA).lastUpdateTime;
            if (lastUpdateTime == mLastUpdateTime) {
                // All good. Do nothing
                return;
            }
            // App has been updated since we load metadata last time. Reload metadata.
            mActivityInfo = null;
            getActivityInfo(context);
            mLastUpdateTime = lastUpdateTime;
        } catch (PackageManager.NameNotFoundException e) {
            Log.d(TAG, "Can't find package, probably uninstalled.");
        }
    }

    private ActivityInfo getActivityInfo(Context context) {
        if (mActivityInfo == null) {
            final PackageManager pm = context.getApplicationContext().getPackageManager();
@@ -309,6 +339,7 @@ public class Tile implements Parcelable {
                    pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
            if (infoList != null && !infoList.isEmpty()) {
                mActivityInfo = infoList.get(0).activityInfo;
                mMetaData = mActivityInfo.metaData;
            }
        }
        return mActivityInfo;
+27 −1
Original line number Diff line number Diff line
@@ -9,7 +9,11 @@ import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;

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

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;

import org.junit.Before;
@@ -17,17 +21,22 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowPackageManager;

@RunWith(RobolectricTestRunner.class)
public class TileTest {

    private Context mContext;
    private ActivityInfo mActivityInfo;
    private Tile mTile;

    @Before
    public void setUp() {
        mContext = RuntimeEnvironment.application;
        mActivityInfo = new ActivityInfo();
        mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName();
        mActivityInfo.applicationInfo = new ApplicationInfo();
        mActivityInfo.packageName = mContext.getPackageName();
        mActivityInfo.name = "abc";
        mActivityInfo.icon = com.android.internal.R.drawable.ic_plus;
        mActivityInfo.metaData = new Bundle();
@@ -143,4 +152,21 @@ public class TileTest {

        assertThat(tile.getOrder()).isEqualTo(1);
    }

    @Test
    public void getTitle_shouldEnsureMetadataNotStale() {
        final ResolveInfo info = new ResolveInfo();
        info.activityInfo = mActivityInfo;
        final ShadowPackageManager spm = Shadow.extract(mContext.getPackageManager());
        spm.addResolveInfoForIntent(
                new Intent().setClassName(mActivityInfo.packageName, mActivityInfo.name), info);

        final Tile tile = new Tile(mActivityInfo, "category");
        final long staleTimeStamp = -10000;
        tile.mLastUpdateTime = staleTimeStamp;

        tile.getTitle(RuntimeEnvironment.application);

        assertThat(tile.mLastUpdateTime).isNotEqualTo(staleTimeStamp);
    }
}