Merge "QS custom tiles - better handling of invalid icons" into nyc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index d04a2fc..9bc85c8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -144,14 +144,18 @@
                 String packageName = info.serviceInfo.packageName;
                 ComponentName componentName = new ComponentName(packageName, info.serviceInfo.name);
                 String spec = CustomTile.toSpec(componentName);
+                if (info.serviceInfo.icon == 0) {
+                    continue;
+                }
                 Drawable icon = info.serviceInfo.loadIcon(pm);
                 if (!permission.BIND_QUICK_SETTINGS_TILE.equals(info.serviceInfo.permission)) {
                     continue;
                 }
-                if (icon != null) {
-                    icon.mutate();
-                    icon.setTint(mContext.getColor(android.R.color.white));
+                if (icon == null) {
+                    continue;
                 }
+                icon.mutate();
+                icon.setTint(mContext.getColor(android.R.color.white));
                 CharSequence label = info.serviceInfo.loadLabel(pm);
                 final CharSequence appLabel = info.serviceInfo.applicationInfo.loadLabel(pm);
                 addTile(spec, icon, label != null ? label.toString() : "null", appLabel, mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 6b20681..54dd015 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -36,7 +36,6 @@
 import android.view.IWindowManager;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
@@ -59,6 +58,7 @@
     private final IQSTileService mService;
     private final TileServiceManager mServiceManager;
     private final int mUser;
+    private final android.graphics.drawable.Icon mDefaultIcon;
 
     private boolean mListening;
     private boolean mBound;
@@ -73,15 +73,19 @@
         mService = mServiceManager.getTileService();
         mTile = new Tile(mComponent);
         mUser = ActivityManager.getCurrentUser();
+        android.graphics.drawable.Icon defaultIcon;
         try {
             PackageManager pm = mContext.getPackageManager();
             ServiceInfo info = pm.getServiceInfo(mComponent,
                     PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
-            mTile.setIcon(android.graphics.drawable.Icon
-                    .createWithResource(mComponent.getPackageName(), info.icon));
+            defaultIcon = info.icon != 0 ? android.graphics.drawable.Icon
+                    .createWithResource(mComponent.getPackageName(), info.icon) : null;
+            mTile.setIcon(defaultIcon);
             mTile.setLabel(info.loadLabel(pm));
         } catch (Exception e) {
+            defaultIcon = null;
         }
+        mDefaultIcon = defaultIcon;
         try {
             mService.setQSTile(mTile);
         } catch (RemoteException e) {
@@ -91,13 +95,7 @@
 
     @Override
     public boolean isAvailable() {
-        try {
-            ServiceInfo info = mContext.getPackageManager().getServiceInfo(mComponent,
-                    PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
+        return mDefaultIcon != null;
     }
 
     public int getUser() {
@@ -227,11 +225,18 @@
 
     @Override
     protected void handleUpdateState(State state, Object arg) {
-        Drawable drawable = mTile.getIcon().loadDrawable(mContext);
         int tileState = mTile.getState();
         if (mServiceManager.hasPendingBind()) {
             tileState = Tile.STATE_UNAVAILABLE;
         }
+        Drawable drawable;
+        try {
+            drawable = mTile.getIcon().loadDrawable(mContext);
+        } catch (Exception e) {
+            Log.w(TAG, "Invalid icon, forcing into unavailable state");
+            tileState = Tile.STATE_UNAVAILABLE;
+            drawable = mDefaultIcon.loadDrawable(mContext);
+        }
         int color = mContext.getColor(getColor(tileState));
         drawable.setTint(color);
         state.icon = new DrawableIcon(drawable);