Icon support comes to Notification.

  And you may ask yourself: what is that beautiful icon?
  And you may ask yourself: where does that API go to?
  And you may ask yourself: is it a resource? is it a Bitmap?
  And you may say to yourself: my god, what have I done

(This patch fixes a number of bugs in the initial
implementation, but other than that, it's the same as it
ever was.)

Bug: 18568715
Bug: 21141842
Change-Id: I1d3f9427abd7f0bb57e533fcfac708851ff644b6
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 715f4e4..be33085 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -194,7 +194,7 @@
         // we compose the final post-save notification below.
         mNotificationBuilder.setLargeIcon(croppedIcon);
         // But we still don't set it for the expanded view, allowing the smallIcon to show here.
-        mNotificationStyle.bigLargeIcon(null);
+        mNotificationStyle.bigLargeIcon((Bitmap) null);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2913c7d..1e488f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1390,9 +1390,9 @@
             final ImageView profileBadge = (ImageView) publicViewLocal.findViewById(
                     R.id.profile_badge_line3);
 
-            final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(),
+            final StatusBarIcon ic = new StatusBarIcon(
                     entry.notification.getUser(),
-                    entry.notification.getNotification().icon,
+                    entry.notification.getNotification().getSmallIcon(),
                     entry.notification.getNotification().iconLevel,
                     entry.notification.getNotification().number,
                     entry.notification.getNotification().tickerText);
@@ -1770,9 +1770,9 @@
                 sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
         iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
-        final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(),
+        final StatusBarIcon ic = new StatusBarIcon(
                 sbn.getUser(),
-                    n.icon,
+                    n.getSmallIcon(),
                     n.iconLevel,
                     n.number,
                     n.tickerText);
@@ -1916,9 +1916,9 @@
             try {
                 if (entry.icon != null) {
                     // Update the icon
-                    final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+                    final StatusBarIcon ic = new StatusBarIcon(
                             notification.getUser(),
-                            n.icon,
+                            n.getSmallIcon(),
                             n.iconLevel,
                             n.number,
                             n.tickerText);
@@ -1938,9 +1938,9 @@
         }
         if (!updateSuccessful) {
             if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
-            final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+            final StatusBarIcon ic = new StatusBarIcon(
                     notification.getUser(),
-                    n.icon,
+                    n.getSmallIcon(),
                     n.iconLevel,
                     n.number,
                     n.tickerText);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index e6847d8..3294e15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -24,6 +24,7 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -100,13 +101,23 @@
         return a.equals(b);
     }
 
+    public boolean equalIcons(Icon a, Icon b) {
+        if (a == b) return true;
+        if (a.getType() != b.getType()) return false;
+        switch (a.getType()) {
+            case Icon.TYPE_RESOURCE:
+                return a.getResPackage().equals(b.getResPackage()) && a.getResId() == b.getResId();
+            case Icon.TYPE_URI:
+                return a.getUriString().equals(b.getUriString());
+            default:
+                return false;
+        }
+    }
     /**
      * Returns whether the set succeeded.
      */
     public boolean set(StatusBarIcon icon) {
-        final boolean iconEquals = mIcon != null
-                && streq(mIcon.iconPackage, icon.iconPackage)
-                && mIcon.iconId == icon.iconId;
+        final boolean iconEquals = mIcon != null && equalIcons(mIcon.icon, icon.icon);
         final boolean levelEquals = iconEquals
                 && mIcon.iconLevel == icon.iconLevel;
         final boolean visibilityEquals = mIcon != null
@@ -167,45 +178,18 @@
     }
 
     /**
-     * Returns the right icon to use for this item, respecting the iconId and
-     * iconPackage (if set)
+     * Returns the right icon to use for this item
      *
-     * @param context Context to use to get resources if iconPackage is not set
+     * @param context Context to use to get resources
      * @return Drawable for this item, or null if the package or item could not
      *         be found
      */
     public static Drawable getIcon(Context context, StatusBarIcon icon) {
-        Resources r = null;
-
-        if (icon.iconPackage != null) {
-            try {
-                int userId = icon.user.getIdentifier();
-                if (userId == UserHandle.USER_ALL) {
-                    userId = UserHandle.USER_OWNER;
-                }
-                r = context.getPackageManager()
-                        .getResourcesForApplicationAsUser(icon.iconPackage, userId);
-            } catch (PackageManager.NameNotFoundException ex) {
-                Log.e(TAG, "Icon package not found: " + icon.iconPackage);
-                return null;
-            }
-        } else {
-            r = context.getResources();
+        int userId = icon.user.getIdentifier();
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_OWNER;
         }
-
-        if (icon.iconId == 0) {
-            return null;
-        }
-
-        try {
-            return r.getDrawable(icon.iconId);
-        } catch (RuntimeException e) {
-            Log.w(TAG, "Icon not found in "
-                  + (icon.iconPackage != null ? icon.iconId : "<system>")
-                  + ": " + Integer.toHexString(icon.iconId));
-        }
-
-        return null;
+        return icon.icon.loadDrawableAsUser(context, userId);
     }
 
     public StatusBarIcon getStatusBarIcon() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 44168bc..26d1c86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.view.Gravity;
@@ -132,8 +133,7 @@
                     break;
                 } else {
                     StatusBarIcon icon = v.getStatusBarIcon();
-                    icon.iconPackage = iconPkg;
-                    icon.iconId = iconId;
+                    icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId);
                     v.set(icon);
                     v.updateDrawable();
                     return;
@@ -152,4 +152,4 @@
         v.set(icon);
         addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
     }
-}
\ No newline at end of file
+}