diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java index ab215320ac069..f34df75a9ab9b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java @@ -16,13 +16,18 @@ package com.android.systemui.qs.external; import android.app.ActivityManager; +import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.service.quicksettings.IQSTileService; import android.support.annotation.VisibleForTesting; import android.util.Log; +import libcore.util.Objects; /** * Manages the priority which lets {@link TileServices} make decisions about which tiles @@ -68,6 +73,12 @@ public class TileServiceManager { mHandler = handler; mStateManager = tileLifecycleManager; mStateManager.setQSService(tileServices); + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addDataScheme("package"); + mServices.getContext().registerReceiverAsUser(mUninstallReceiver, + new UserHandle(ActivityManager.getCurrentUser()), filter, null, mHandler); } public boolean isActiveTile() { @@ -106,6 +117,7 @@ public class TileServiceManager { } public void handleDestroy() { + mServices.getContext().unregisterReceiver(mUninstallReceiver); mStateManager.handleDestroy(); } @@ -198,4 +210,23 @@ public class TileServiceManager { mServices.recalculateBindAllowance(); } }; + + private final BroadcastReceiver mUninstallReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { + return; + } + if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + return; + } + Uri data = intent.getData(); + String pkgName = data.getEncodedSchemeSpecificPart(); + final ComponentName component = mStateManager.getComponent(); + if (!Objects.equal(pkgName, component.getPackageName())) { + return; + } + mServices.getHost().removeTile(component); + } + }; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java index f36d013b85965..2ab6b5fc98e91 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java @@ -72,6 +72,10 @@ public class TileServices extends IQSService.Stub { return mContext; } + public QSTileHost getHost() { + return mHost; + } + public TileServiceManager getTileWrapper(CustomTile tile) { ComponentName component = tile.getComponent(); TileServiceManager service = onCreateTileService(component); @@ -89,6 +93,7 @@ public class TileServices extends IQSService.Stub { public void freeService(CustomTile tile, TileServiceManager service) { synchronized (mServices) { service.setBindAllowed(false); + service.handleDestroy(); mServices.remove(tile); mTiles.remove(tile.getComponent()); final String slot = tile.getComponent().getClassName();