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

Commit 624cbe2d authored by Jason Monk's avatar Jason Monk
Browse files

Update QS custom tile icons when they change

When an app updates to change their default tile icon, pick up on
the change.  When listening this comes from the TileLifecycleManager
and when not listening this guts picked up next time listening starts.

Change-Id: Ib730f02ed54ca1c1ba72ce50adf7dcf91f01738f
Fixes: 27911877
parent 4a992cbd
Loading
Loading
Loading
Loading
+56 −12
Original line number Diff line number Diff line
@@ -40,9 +40,11 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
import com.android.systemui.statusbar.phone.QSTileHost;
import libcore.util.Objects;

public class CustomTile extends QSTile<QSTile.State> {
public class CustomTile extends QSTile<QSTile.State> implements TileChangeListener {
    public static final String PREFIX = "custom(";

    private static final boolean DEBUG = false;
@@ -58,7 +60,7 @@ public class CustomTile extends QSTile<QSTile.State> {
    private final IQSTileService mService;
    private final TileServiceManager mServiceManager;
    private final int mUser;
    private final android.graphics.drawable.Icon mDefaultIcon;
    private android.graphics.drawable.Icon mDefaultIcon;

    private boolean mListening;
    private boolean mBound;
@@ -71,26 +73,66 @@ public class CustomTile extends QSTile<QSTile.State> {
        mComponent = ComponentName.unflattenFromString(action);
        mServiceManager = host.getTileServices().getTileWrapper(this);
        mService = mServiceManager.getTileService();
        mServiceManager.setTileChangeListener(this);
        mTile = new Tile(mComponent);
        mUser = ActivityManager.getCurrentUser();
        android.graphics.drawable.Icon defaultIcon;
        setTileIcon();
        try {
            mService.setQSTile(mTile);
        } catch (RemoteException e) {
            // Called through wrapper, won't happen here.
        }
    }

    private void setTileIcon() {
        try {
            PackageManager pm = mContext.getPackageManager();
            ServiceInfo info = pm.getServiceInfo(mComponent,
                    PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
            defaultIcon = info.icon != 0 ? android.graphics.drawable.Icon
            // Update the icon if its not set or is the default icon.
            boolean updateIcon = mTile.getIcon() == null
                    || iconEquals(mTile.getIcon(), mDefaultIcon);
            mDefaultIcon = info.icon != 0 ? android.graphics.drawable.Icon
                    .createWithResource(mComponent.getPackageName(), info.icon) : null;
            mTile.setIcon(defaultIcon);
            if (updateIcon) {
                mTile.setIcon(mDefaultIcon);
            }
            // Update the label if there is no label.
            if (mTile.getLabel() == null) {
                mTile.setLabel(info.loadLabel(pm));
            }
        } catch (Exception e) {
            defaultIcon = null;
            mDefaultIcon = null;
        }
        mDefaultIcon = defaultIcon;
        try {
            mService.setQSTile(mTile);
        } catch (RemoteException e) {
            // Called through wrapper, won't happen here.
    }

    /**
     * Compare two icons, only works for resources.
     */
    private boolean iconEquals(android.graphics.drawable.Icon icon1,
            android.graphics.drawable.Icon icon2) {
        if (icon1 == icon2) {
            return true;
        }
        if (icon1 == null || icon2 == null) {
            return false;
        }
        if (icon1.getType() != android.graphics.drawable.Icon.TYPE_RESOURCE
                || icon2.getType() != android.graphics.drawable.Icon.TYPE_RESOURCE) {
            return false;
        }
        if (icon1.getResId() != icon2.getResId()) {
            return false;
        }
        if (!Objects.equal(icon1.getResPackage(), icon2.getResPackage())) {
            return false;
        }
        return true;
    }

    @Override
    public void onTileChanged(ComponentName tile) {
        setTileIcon();
    }

    @Override
@@ -136,6 +178,8 @@ public class CustomTile extends QSTile<QSTile.State> {
        mListening = listening;
        try {
            if (listening) {
                setTileIcon();
                refreshState();
                if (!mServiceManager.isActiveTile()) {
                    mServiceManager.setBindRequested(true);
                    mService.onStartListening();
+13 −1
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
    boolean mReceiverRegistered;
    private IQSService mService;
    private boolean mUnbindImmediate;
    private TileChangeListener mChangeListener;

    public TileLifecycleManager(Handler handler, Context context, Intent intent, UserHandle user) {
        mContext = context;
@@ -168,7 +169,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
    @Override
    public void onServiceDisconnected(ComponentName name) {
        if (DEBUG) Log.d(TAG, "onServiceDisconnected " + name);
        mWrapper = null;
        handleDeath();
    }

    private void handlePendingMessages() {
@@ -279,6 +280,10 @@ public class TileLifecycleManager extends BroadcastReceiver implements
        mReceiverRegistered = false;
    }

    public void setTileChangeListener(TileChangeListener changeListener) {
        mChangeListener = changeListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (DEBUG) Log.d(TAG, "onReceive: " + intent);
@@ -289,6 +294,9 @@ public class TileLifecycleManager extends BroadcastReceiver implements
                return;
            }
        }
        if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) && mChangeListener != null) {
            mChangeListener.onTileChanged(mIntent.getComponent());
        }
        stopPackageListening();
        if (mBound) {
            // Trying to bind again will check the state of the package before bothering to bind.
@@ -401,4 +409,8 @@ public class TileLifecycleManager extends BroadcastReceiver implements
        if (DEBUG) Log.d(TAG, "binderDeath");
        handleDeath();
    }

    public interface TileChangeListener {
        void onTileChanged(ComponentName tile);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.UserHandle;
import android.service.quicksettings.IQSTileService;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
import libcore.util.Objects;

/**
@@ -81,6 +82,10 @@ public class TileServiceManager {
                new UserHandle(ActivityManager.getCurrentUser()), filter, null, mHandler);
    }

    public void setTileChangeListener(TileChangeListener changeListener) {
        mStateManager.setTileChangeListener(changeListener);
    }

    public boolean isActiveTile() {
        return mStateManager.isActiveTile();
    }