Remove QS tiles that get uninstalled

Change-Id: Ib4c7250a38c0630b0d828f1f55ce5c0dc4d3bb44
Fixes: 27893200
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 ab21532..f34df75 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 @@
         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 void handleDestroy() {
+        mServices.getContext().unregisterReceiver(mUninstallReceiver);
         mStateManager.handleDestroy();
     }
 
@@ -198,4 +210,23 @@
             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 f36d013..2ab6b5f 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 @@
         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 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();