Merge "Icon API tuneups:" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 08d6a9d..57d1c6d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12405,10 +12405,11 @@
     method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
     method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
     method public static android.graphics.drawable.Icon createWithResource(android.content.res.Resources, int);
+    method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
     method public int describeContents();
     method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
     method public void loadDrawableAsync(android.content.Context, android.os.Message);
-    method public void loadDrawableAsync(android.content.Context, android.os.Handler, android.graphics.drawable.Icon.OnDrawableLoadedListener);
+    method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 7cf49e8..204a0b4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -12711,10 +12711,11 @@
     method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
     method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
     method public static android.graphics.drawable.Icon createWithResource(android.content.res.Resources, int);
+    method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
     method public int describeContents();
     method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
     method public void loadDrawableAsync(android.content.Context, android.os.Message);
-    method public void loadDrawableAsync(android.content.Context, android.os.Handler, android.graphics.drawable.Icon.OnDrawableLoadedListener);
+    method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
   }
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 47a1f77..b2c3ab7 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -29,9 +29,9 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.util.Log;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -177,14 +177,13 @@
      * Invokes {@link #loadDrawable(Context)} on a background thread
      * and then runs <code>andThen</code> on the UI thread when finished.
      *
-     * @param context {@link android.content.Context Context} in which to load the drawable; see
+     * @param context {@link Context Context} in which to load the drawable; see
      *                {@link #loadDrawable(Context)}
-     * @param handler {@link android.os.Handler} on which to run <code>andThen</code>.
      * @param listener a callback to run on the provided
-     *                 Handler once the drawable is available.
+     * @param handler {@link Handler} on which to run <code>andThen</code>.
      */
-    public void loadDrawableAsync(Context context, Handler handler,
-            final OnDrawableLoadedListener listener) {
+    public void loadDrawableAsync(Context context, final OnDrawableLoadedListener listener,
+            Handler handler) {
         new LoadDrawableTask(context, handler, listener).runAsync();
     }
 
@@ -211,14 +210,21 @@
                         try {
                             mObj1 = pm.getResourcesForApplication(getResPackage());
                         } catch (PackageManager.NameNotFoundException e) {
-                            Log.e(TAG,
-                                    String.format("Unable to find package '%s'", getResPackage()),
+                            Log.e(TAG, String.format("Unable to find pkg=%s",
+                                            getResPackage()),
                                     e);
                             break;
                         }
                     }
                 }
-                return getResources().getDrawable(getResId(), context.getTheme());
+                try {
+                    return getResources().getDrawable(getResId(), context.getTheme());
+                } catch (RuntimeException e) {
+                    Log.e(TAG, String.format("Unable to load resource 0x%08x from pkg=%s",
+                                    getResId(),
+                                    getResPackage()),
+                            e);
+                }
             case TYPE_DATA:
                 return new BitmapDrawable(context.getResources(),
                     BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(), getDataLength())
@@ -250,25 +256,62 @@
         return null;
     }
 
+    /**
+     * Load the requested resources under the given userId, if the system allows it,
+     * before actually loading the drawable.
+     *
+     * @hide
+     */
+    public Drawable loadDrawableAsUser(Context context, int userId) {
+        if (mType == TYPE_RESOURCE) {
+            if (getResources() == null
+                    && getResPackage() != null
+                    && !(getResPackage().equals("android"))) {
+                final PackageManager pm = context.getPackageManager();
+                try {
+                    mObj1 = pm.getResourcesForApplicationAsUser(getResPackage(), userId);
+                } catch (PackageManager.NameNotFoundException e) {
+                    Log.e(TAG, String.format("Unable to find pkg=%s user=%d",
+                                    getResPackage(),
+                                    userId),
+                            e);
+                }
+            }
+        }
+        return loadDrawable(context);
+    }
+
     private Icon(int mType) {
         this.mType = mType;
     }
 
     /**
-     * Create a Icon pointing to a drawable resource.
+     * Create an Icon pointing to a drawable resource.
      * @param res Resources for a package containing the resource in question
-     * @param resid ID of the drawable resource
+     * @param resId ID of the drawable resource
      */
-    public static Icon createWithResource(Resources res, @DrawableRes int resid) {
+    public static Icon createWithResource(Resources res, @DrawableRes int resId) {
         final Icon rep = new Icon(TYPE_RESOURCE);
         rep.mObj1 = res;
-        rep.mInt1 = resid;
-        rep.mString1 = res.getResourcePackageName(resid);
+        rep.mInt1 = resId;
+        rep.mString1 = res.getResourcePackageName(resId);
         return rep;
     }
 
     /**
-     * Create a Icon pointing to a bitmap in memory.
+     * Create an Icon pointing to a drawable resource.
+     * @param resPackage Name of the package containing the resource in question
+     * @param resId ID of the drawable resource
+     */
+    public static Icon createWithResource(String resPackage, @DrawableRes int resId) {
+        final Icon rep = new Icon(TYPE_RESOURCE);
+        rep.mInt1 = resId;
+        rep.mString1 = resPackage;
+        return rep;
+    }
+
+    /**
+     * Create an Icon pointing to a bitmap in memory.
      * @param bits A valid {@link android.graphics.Bitmap} object
      */
     public static Icon createWithBitmap(Bitmap bits) {
@@ -278,7 +321,7 @@
     }
 
     /**
-     * Create a Icon pointing to a compressed bitmap stored in a byte array.
+     * Create an Icon pointing to a compressed bitmap stored in a byte array.
      * @param data Byte array storing compressed bitmap data of a type that
      *             {@link android.graphics.BitmapFactory}
      *             can decode (see {@link android.graphics.Bitmap.CompressFormat}).
@@ -294,7 +337,7 @@
     }
 
     /**
-     * Create a Icon pointing to a content specified by URI.
+     * Create an Icon pointing to an image file specified by URI.
      *
      * @param uri A uri referring to local content:// or file:// image data.
      */
@@ -305,7 +348,7 @@
     }
 
     /**
-     * Create a Icon pointing to a content specified by URI.
+     * Create an Icon pointing to an image file specified by URI.
      *
      * @param uri A uri referring to local content:// or file:// image data.
      */
@@ -316,7 +359,7 @@
     }
 
     /**
-     * Create a Icon pointing to
+     * Create an Icon pointing to an image file specified by path.
      *
      * @param path A path to a file that contains compressed bitmap data of
      *           a type that {@link android.graphics.BitmapFactory} can decode.
@@ -437,8 +480,8 @@
     };
 
     /**
-     * Implement this interface to receive notification when
-     * {@link #loadDrawableAsync(Context, Handler, OnDrawableLoadedListener) loadDrawableAsync}
+     * Implement this interface to receive a callback when
+     * {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
      * is finished and your Drawable is ready.
      */
     public interface OnDrawableLoadedListener {
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java b/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
index 2b9bf50..a7f8023 100644
--- a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
+++ b/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
@@ -27,15 +27,11 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.lang.Override;
 import java.util.Arrays;
 import java.util.ArrayList;
 
-import junit.framework.TestCase;
-
 import com.android.frameworks.graphicstests.R;
 
 public class IconTest extends AndroidTestCase {
@@ -173,7 +169,7 @@
         thd.start();
         final Handler h = new Handler(thd.getLooper());
         L(TAG, "asyncTest: dispatching load to thread: " + thd);
-        im1.loadDrawableAsync(mContext, h, new Icon.OnDrawableLoadedListener() {
+        im1.loadDrawableAsync(mContext, new Icon.OnDrawableLoadedListener() {
             @Override
             public void onDrawableLoaded(Drawable draw1) {
                 L(TAG, "asyncTest: thread: loading drawable");
@@ -195,7 +191,7 @@
                     fail("testAsync: file1 differs, check " + dir);
                 }
             }
-        });
+        }, h);
         L(TAG, "asyncTest: awaiting result");
         Thread.sleep(500); // ;_;
         assertTrue("async-test.png does not exist!", new File(dir, "async-test.png").exists());