Merge "Make background projection a property of View"
diff --git a/api/current.txt b/api/current.txt
index 7673ff3..94ffb30 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6201,6 +6201,7 @@
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
     method public abstract java.io.File getDir(java.lang.String, int);
+    method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
     method public abstract java.io.File[] getExternalCacheDirs();
     method public abstract java.io.File getExternalFilesDir(java.lang.String);
@@ -8012,7 +8013,9 @@
     method public int getDimensionPixelSize(int) throws android.content.res.Resources.NotFoundException;
     method public android.util.DisplayMetrics getDisplayMetrics();
     method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
     method public android.graphics.drawable.Drawable getDrawableForDensity(int, int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawableForDensity(int, int, android.content.res.Resources.Theme);
     method public float getFraction(int, int, int);
     method public int getIdentifier(java.lang.String, java.lang.String, java.lang.String);
     method public int[] getIntArray(int) throws android.content.res.Resources.NotFoundException;
@@ -8056,6 +8059,7 @@
   public final class Resources.Theme {
     method public void applyStyle(int, boolean);
     method public void dump(int, java.lang.String, java.lang.String);
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet, int[], int, int);
@@ -10647,11 +10651,24 @@
     ctor public RotateDrawable();
     method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
+    method public float getFromDegrees();
     method public int getOpacity();
+    method public float getPivotX();
+    method public float getPivotY();
+    method public float getToDegrees();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public boolean isPivotXRelative();
+    method public boolean isPivotYRelative();
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setFromDegrees(float);
+    method public void setPivotX(float);
+    method public void setPivotXRelative(boolean);
+    method public void setPivotY(float);
+    method public void setPivotYRelative(boolean);
+    method public void setToDegrees(float);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
 
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index bfbae24..242b3ea 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -100,7 +100,7 @@
             try {
                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
             } catch (PackageManager.NameNotFoundException e) {
                 // Nothing we can do much here, just log
                 if (Log.isLoggable(TAG, Log.WARN)) {
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index acc8549..a3222d8 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -129,7 +129,7 @@
             Drawable icon = null;
             try {
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
                 final CharSequence sequence = authContext.getResources().getText(desc.labelId);
                 if (sequence != null) {
                     name = sequence.toString();
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d04e9db..af1810b 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -188,8 +188,7 @@
                 mSearchView.findViewById(com.android.internal.R.id.search_src_text);
         mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon);
         mSearchPlate = mSearchView.findViewById(com.android.internal.R.id.search_plate);
-        mWorkingSpinner = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.search_spinner);
+        mWorkingSpinner = getContext().getDrawable(com.android.internal.R.drawable.search_spinner);
         // TODO: Restore the spinner for slow suggestion lookups
         // mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
         //        null, null, mWorkingSpinner, null);
@@ -458,7 +457,7 @@
 
         // optionally show one or the other.
         if (mSearchable.useBadgeIcon()) {
-            icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
+            icon = mActivityContext.getDrawable(mSearchable.getIconId());
             visibility = View.VISIBLE;
             if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
         } else if (mSearchable.useBadgeLabel()) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ac08d9b..9f90de0 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -376,6 +376,19 @@
         return getResources().getString(resId, formatArgs);
     }
 
+    /**
+     * Return a drawable object associated with a particular resource ID and
+     * styled for the current theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt
+     *           tool. This integer encodes the package, type, and resource
+     *           entry. The value 0 is an invalid identifier.
+     * @return Drawable An object that can be used to draw this resource.
+     */
+    public final Drawable getDrawable(int id) {
+        return getResources().getDrawable(id, getTheme());
+    }
+
      /**
      * Set the base theme for this context.  Note that this should be called
      * before any views are instantiated in the Context (for example before
diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java
index 350f35e..093fb08 100644
--- a/core/java/android/content/SyncActivityTooManyDeletes.java
+++ b/core/java/android/content/SyncActivityTooManyDeletes.java
@@ -95,7 +95,7 @@
 //                try {
 //                    final Context authContext = createPackageContext(desc.packageName, 0);
 //                    ImageView imageView = new ImageView(this);
-//                    imageView.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
+//                    imageView.setImageDrawable(authContext.getDrawable(desc.iconId));
 //                    ll.addView(imageView, lp);
 //                } catch (PackageManager.NameNotFoundException e) {
 //                }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 185bfd8..aa96f0e 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -686,12 +686,27 @@
      * @param id The desired resource identifier, as generated by the aapt
      *           tool. This integer encodes the package, type, and resource
      *           entry. The value 0 is an invalid identifier.
-     *
-     * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
-     * 
      * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *         not exist.
      */
     public Drawable getDrawable(int id) throws NotFoundException {
+        return getDrawable(id, null);
+    }
+
+    /**
+     * Return a drawable object associated with a particular resource ID and
+     * styled for the specified theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt
+     *           tool. This integer encodes the package, type, and resource
+     *           entry. The value 0 is an invalid identifier.
+     * @param theme The theme used to style the drawable attributes.
+     * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *         not exist.
+     */
+    public Drawable getDrawable(int id, Theme theme) throws NotFoundException {
         TypedValue value;
         synchronized (mAccessLock) {
             value = mTmpValue;
@@ -702,7 +717,7 @@
             }
             getValue(id, value, true);
         }
-        Drawable res = loadDrawable(value, id);
+        final Drawable res = loadDrawable(value, id, theme);
         synchronized (mAccessLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
@@ -720,17 +735,36 @@
      * depending on the underlying resource -- for example, a solid color, PNG
      * image, scalable image, etc. The Drawable API hides these implementation
      * details.
-     * 
+     *
      * @param id The desired resource identifier, as generated by the aapt tool.
      *            This integer encodes the package, type, and resource entry.
      *            The value 0 is an invalid identifier.
      * @param density the desired screen density indicated by the resource as
      *            found in {@link DisplayMetrics}.
+     * @return Drawable An object that can be used to draw this resource.
      * @throws NotFoundException Throws NotFoundException if the given ID does
      *             not exist.
-     * @return Drawable An object that can be used to draw this resource.
+     * @see #getDrawableForDensity(int, int, Theme)
      */
     public Drawable getDrawableForDensity(int id, int density) throws NotFoundException {
+        return getDrawableForDensity(id, density, null);
+    }
+
+    /**
+     * Return a drawable object associated with a particular resource ID for the
+     * given screen density in DPI and styled for the specified theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt tool.
+     *            This integer encodes the package, type, and resource entry.
+     *            The value 0 is an invalid identifier.
+     * @param density The desired screen density indicated by the resource as
+     *            found in {@link DisplayMetrics}.
+     * @param theme The theme used to style the drawable attributes.
+     * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *             not exist.
+     */
+    public Drawable getDrawableForDensity(int id, int density, Theme theme) {
         TypedValue value;
         synchronized (mAccessLock) {
             value = mTmpValue;
@@ -757,7 +791,7 @@
             }
         }
 
-        Drawable res = loadDrawable(value, id);
+        final Drawable res = loadDrawable(value, id, theme);
         synchronized (mAccessLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
@@ -1251,8 +1285,9 @@
          * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
          */
         public TypedArray obtainStyledAttributes(int[] attrs) {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
+            array.mTheme = this;
             array.mRsrcs = attrs;
             AssetManager.applyStyle(mTheme, 0, 0, 0, attrs,
                     array.mData, array.mIndices);
@@ -1279,10 +1314,10 @@
          * @see #obtainStyledAttributes(int[])
          * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
          */
-        public TypedArray obtainStyledAttributes(int resid, int[] attrs)
-                throws NotFoundException {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+        public TypedArray obtainStyledAttributes(int resid, int[] attrs) throws NotFoundException {
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
+            array.mTheme = this;
             array.mRsrcs = attrs;
 
             AssetManager.applyStyle(mTheme, 0, resid, 0, attrs,
@@ -1366,19 +1401,18 @@
          */
         public TypedArray obtainStyledAttributes(AttributeSet set,
                 int[] attrs, int defStyleAttr, int defStyleRes) {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
 
             // XXX note that for now we only work with compiled XML files.
             // To support generic XML files we will need to manually parse
             // out the attributes from the XML file (applying type information
             // contained in the resources and such).
-            XmlBlock.Parser parser = (XmlBlock.Parser)set;
-            AssetManager.applyStyle(
-                mTheme, defStyleAttr, defStyleRes,
-                parser != null ? parser.mParseState : 0, attrs,
-                        array.mData, array.mIndices);
+            final XmlBlock.Parser parser = (XmlBlock.Parser)set;
+            AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
+                    parser != null ? parser.mParseState : 0, attrs, array.mData, array.mIndices);
 
+            array.mTheme = this;
             array.mRsrcs = attrs;
             array.mXml = parser;
 
@@ -1444,6 +1478,21 @@
         }
 
         /**
+         * Return a drawable object associated with a particular resource ID
+         * and styled for the Theme.
+         *
+         * @param id The desired resource identifier, as generated by the aapt
+         *           tool. This integer encodes the package, type, and resource
+         *           entry. The value 0 is an invalid identifier.
+         * @return Drawable An object that can be used to draw this resource.
+         * @throws NotFoundException Throws NotFoundException if the given ID
+         *         does not exist.
+         */
+        public Drawable getDrawable(int id) throws NotFoundException {
+            return Resources.this.getDrawable(id, this);
+        }
+
+        /**
          * Print contents of this theme out to the log.  For debugging only.
          * 
          * @param priority The log priority to use.
@@ -1453,7 +1502,8 @@
         public void dump(int priority, String tag, String prefix) {
             AssetManager.dumpTheme(mTheme, priority, tag, prefix);
         }
-        
+
+        @Override
         protected void finalize() throws Throwable {
             super.finalize();
             mAssets.releaseTheme(mTheme);
@@ -1464,6 +1514,7 @@
             mTheme = mAssets.createTheme();
         }
 
+        @SuppressWarnings("hiding")
         private final AssetManager mAssets;
         private final long mTheme;
     }
@@ -2028,14 +2079,14 @@
         return true;
     }
 
-    /*package*/ Drawable loadDrawable(TypedValue value, int id)
-            throws NotFoundException {
-
+    /*package*/ Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
         if (TRACE_FOR_PRELOAD) {
             // Log only framework resources
             if ((id >>> 24) == 0x1) {
                 final String name = getResourceName(id);
-                if (name != null) android.util.Log.d("PreloadDrawable", name);
+                if (name != null) {
+                    Log.d("PreloadDrawable", name);
+                }
             }
         }
 
@@ -2240,12 +2291,12 @@
                     "Resource is not a ColorStateList (color or path): " + value);
         }
         
-        String file = value.string.toString();
+        final String file = value.string.toString();
 
         if (file.endsWith(".xml")) {
             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, file);
             try {
-                XmlResourceParser rp = loadXmlResourceParser(
+                final XmlResourceParser rp = loadXmlResourceParser(
                         file, id, value.assetCookie, "colorstatelist"); 
                 csl = ColorStateList.createFromXml(this, rp);
                 rp.close();
@@ -2372,7 +2423,6 @@
         synchronized (mAccessLock) {
             final TypedArray cached = mCachedStyledAttributes;
             if (cached == null || cached.mData.length < attrs.mData.length) {
-                attrs.mXml = null;
                 mCachedStyledAttributes = attrs;
             }
         }
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 87d65a5..4858d08 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -45,7 +45,8 @@
     /*package*/ int[] mIndices;
     /*package*/ int mLength;
     /*package*/ TypedValue mValue = new TypedValue();
-   
+    /*package*/ Resources.Theme mTheme;
+
     /**
      * Return the number of values in this array.
      */
@@ -600,7 +601,7 @@
                                    + " cookie=" + value.assetCookie);
                 System.out.println("******************************************************************");
             }
-            return mResources.loadDrawable(value, value.resourceId);
+            return mResources.loadDrawable(value, value.resourceId, mTheme);
         }
         return null;
     }
@@ -690,6 +691,10 @@
      */
     public void recycle() {
         mResources.recycleCachedStyledAttributes(this);
+
+        mXml = null;
+        mRsrcs = null;
+        mTheme = null;
     }
 
     private boolean getValueAt(int index, TypedValue outValue) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 8048b24..bb8b184 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -255,11 +255,18 @@
             new Key<byte[]>("android.control.awbAvailableModes", byte[].class);
 
     /**
-     * <p>For AE, AWB, and AF, how many individual
-     * regions can be listed for metering?</p>
+     * <p>List of the maximum number of regions that can be used for metering in
+     * auto-exposure (AE), auto-white balance (AWB), and auto-focus (AF);
+     * this corresponds to the the maximum number of elements in
+     * {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}, {@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions},
+     * and {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_REGIONS
+     * @see CaptureRequest#CONTROL_AF_REGIONS
+     * @see CaptureRequest#CONTROL_AWB_REGIONS
      */
-    public static final Key<Integer> CONTROL_MAX_REGIONS =
-            new Key<Integer>("android.control.maxRegions", int.class);
+    public static final Key<int[]> CONTROL_MAX_REGIONS =
+            new Key<int[]>("android.control.maxRegions", int[].class);
 
     /**
      * <p>Whether this camera device has a
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 0988c62..1327ba9 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -510,9 +510,9 @@
 
     /**
      * <p>List of areas to use for
-     * metering</p>
+     * metering.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -524,7 +524,7 @@
      * needs to be used by the HAL. If the metering region is
      * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
      * should ignore the sections outside the region and output the
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -582,9 +582,9 @@
 
     /**
      * <p>List of areas to use for focus
-     * estimation</p>
+     * estimation.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -596,7 +596,7 @@
      * needs to be used by the HAL. If the focusing region is
      * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
      * should ignore the sections outside the region and output the
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -668,10 +668,10 @@
 
     /**
      * <p>List of areas to use for illuminant
-     * estimation</p>
+     * estimation.</p>
      * <p>Only used in AUTO mode.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -683,7 +683,7 @@
      * needs to be used by the HAL. If the metering region is
      * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
      * should ignore the sections outside the region and output the
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 1f65c19..46d95b1 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -212,9 +212,9 @@
 
     /**
      * <p>List of areas to use for
-     * metering</p>
+     * metering.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -226,7 +226,7 @@
      * needs to be used by the HAL. If the metering region is
      * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
      * should ignore the sections outside the region and output the
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -405,9 +405,9 @@
 
     /**
      * <p>List of areas to use for focus
-     * estimation</p>
+     * estimation.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -419,7 +419,7 @@
      * needs to be used by the HAL. If the focusing region is
      * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
      * should ignore the sections outside the region and output the
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -794,10 +794,10 @@
 
     /**
      * <p>List of areas to use for illuminant
-     * estimation</p>
+     * estimation.</p>
      * <p>Only used in AUTO mode.</p>
      * <p>Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * xmax, ymax, weight. The rectangle is defined to be inclusive of the
      * specified coordinates.</p>
      * <p>The coordinate system is based on the active pixel array,
      * with (0,0) being the top-left pixel in the active pixel array, and
@@ -809,7 +809,7 @@
      * needs to be used by the HAL. If the metering region is
      * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
      * should ignore the sections outside the region and output the
-     * used sections in the frame metadata</p>
+     * used sections in the frame metadata.</p>
      *
      * @see CaptureRequest#SCALER_CROP_REGION
      * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index 5275bc0..b65eac7 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -169,7 +169,7 @@
      * @param dialogIconRes The icon, as a resource ID.
      */
     public void setDialogIcon(int dialogIconRes) {
-        mDialogIcon = getContext().getResources().getDrawable(dialogIconRes);
+        mDialogIcon = getContext().getDrawable(dialogIconRes);
     }
     
     /**
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 76fccc7..144c909 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -561,7 +561,7 @@
         if (imageView != null) {
             if (mIconResId != 0 || mIcon != null) {
                 if (mIcon == null) {
-                    mIcon = getContext().getResources().getDrawable(mIconResId);
+                    mIcon = getContext().getDrawable(mIconResId);
                 }
                 if (mIcon != null) {
                     imageView.setImageDrawable(mIcon);
@@ -694,7 +694,7 @@
      */
     public void setIcon(int iconResId) {
         mIconResId = iconResId;
-        setIcon(mContext.getResources().getDrawable(iconResId));
+        setIcon(mContext.getDrawable(iconResId));
     }
 
     /**
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 74b9463..3d6f8e6 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -145,7 +145,7 @@
             }
         } else {
             try {
-                drawable = mContext.getResources().getDrawable(mResourceId);
+                drawable = mContext.getDrawable(mResourceId);
                 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                         drawable.getIntrinsicHeight());
             } catch (Exception e) {
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index bb7ed41..063a08d 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -140,7 +140,7 @@
         if ((resourceId & 0xff000000) == 0x01000000) {
             icon.mSystemIconResourceId = resourceId;
         } else {
-            icon.loadResource(context.getResources(), resourceId);
+            icon.loadResource(context, context.getResources(), resourceId);
         }
         return icon;
     }
@@ -198,7 +198,7 @@
         }
 
         PointerIcon icon = new PointerIcon(STYLE_CUSTOM);
-        icon.loadResource(resources, resourceId);
+        icon.loadResource(null, resources, resourceId);
         return icon;
     }
 
@@ -224,7 +224,7 @@
 
         PointerIcon result = new PointerIcon(mStyle);
         result.mSystemIconResourceId = mSystemIconResourceId;
-        result.loadResource(context.getResources(), mSystemIconResourceId);
+        result.loadResource(context, context.getResources(), mSystemIconResourceId);
         return result;
     }
 
@@ -373,7 +373,7 @@
         return true;
     }
 
-    private void loadResource(Resources resources, int resourceId) {
+    private void loadResource(Context context, Resources resources, int resourceId) {
         XmlResourceParser parser = resources.getXml(resourceId);
         final int bitmapRes;
         final float hotSpotX;
@@ -397,7 +397,12 @@
             throw new IllegalArgumentException("<pointer-icon> is missing bitmap attribute.");
         }
 
-        Drawable drawable = resources.getDrawable(bitmapRes);
+        Drawable drawable;
+        if (context == null) {
+            drawable = resources.getDrawable(bitmapRes);
+        } else {
+            drawable = context.getDrawable(bitmapRes);
+        }
         if (!(drawable instanceof BitmapDrawable)) {
             throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
                     + "refer to a bitmap drawable.");
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 55dcbb2..97a1f21 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -177,13 +177,13 @@
      * Equivalent to calling hide().
      * Updates the value set during Surface creation (see {@link #HIDDEN}).
      */
-    public static final int SURFACE_HIDDEN = 0x01;
+    private static final int SURFACE_HIDDEN = 0x01;
 
     /**
      * Surface flag: composite without blending when possible.
      * Updates the value set during Surface creation (see {@link #OPAQUE}).
      */
-    public static final int SURFACE_OPAQUE = 0x02;
+    private static final int SURFACE_OPAQUE = 0x02;
 
 
     /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
@@ -191,13 +191,13 @@
 
     /**
      * Built-in physical display id: Main display.
-     * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+     * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
      */
     public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
 
     /**
      * Built-in physical display id: Attached HDMI display.
-     * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+     * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
      */
     public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
 
@@ -369,18 +369,6 @@
         nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
     }
 
-    /**
-     * Sets and clears flags, such as {@link #SURFACE_HIDDEN}.  The new value will be:
-     * <p>
-     *   <code>newFlags = (oldFlags & ~mask) | (flags & mask)</code>
-     * <p>
-     * Note this does not take the same set of flags as the constructor.
-     */
-    public void setFlags(int flags, int mask) {
-        checkNotReleased();
-        nativeSetFlags(mNativeObject, flags, mask);
-    }
-
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
         if (crop != null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index dc382a0..12dc044 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15699,7 +15699,7 @@
 
         Drawable d= null;
         if (resid != 0) {
-            d = mResources.getDrawable(resid);
+            d = mContext.getDrawable(resid);
         }
         setBackground(d);
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5aa46f3..ccb85a6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2592,7 +2592,7 @@
                         R.attr.accessibilityFocusedDrawable, value, true);
                 if (resolved) {
                     mAttachInfo.mAccessibilityFocusDrawable =
-                        mView.mContext.getResources().getDrawable(value.resourceId);
+                        mView.mContext.getDrawable(value.resourceId);
                 }
             }
             return mAttachInfo.mAccessibilityFocusDrawable;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2f62431..1064a08 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1039,7 +1039,7 @@
      */
     public void setBackgroundDrawableResource(int resid)
     {
-        setBackgroundDrawable(mContext.getResources().getDrawable(resid));
+        setBackgroundDrawable(mContext.getDrawable(resid));
     }
 
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4d8975c..13febe9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1604,7 +1604,7 @@
     }
 
     private void useDefaultSelector() {
-        setSelector(getResources().getDrawable(
+        setSelector(getContext().getDrawable(
                 com.android.internal.R.drawable.list_selector_background));
     }
 
@@ -2616,7 +2616,7 @@
      * @attr ref android.R.styleable#AbsListView_listSelector
      */
     public void setSelector(int resID) {
-        setSelector(getResources().getDrawable(resID));
+        setSelector(getContext().getDrawable(resID));
     }
 
     public void setSelector(Drawable sel) {
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 3c88e94..5b80648 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -80,17 +80,17 @@
 
         mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
         if (mDial == null) {
-            mDial = r.getDrawable(com.android.internal.R.drawable.clock_dial);
+            mDial = context.getDrawable(com.android.internal.R.drawable.clock_dial);
         }
 
         mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour);
         if (mHourHand == null) {
-            mHourHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
+            mHourHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
         }
 
         mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);
         if (mMinuteHand == null) {
-            mMinuteHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
+            mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
         }
 
         mCalendar = new Time();
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 34cfea5..10e56c7 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -322,7 +322,7 @@
             CharSequence grpName, CharSequence description, boolean dangerous) {
         LayoutInflater inflater = (LayoutInflater)context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
-        Drawable icon = context.getResources().getDrawable(dangerous
+        Drawable icon = context.getDrawable(dangerous
                 ? R.drawable.ic_bullet_key_permission : R.drawable.ic_text_dot);
         return getPermissionItemViewOld(context, inflater, grpName,
                 description, dangerous, icon);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 259c66b9..eb232fd 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -366,7 +366,7 @@
      * @attr ref android.R.styleable#PopupWindow_popupBackground
      */
     public void setDropDownBackgroundResource(int id) {
-        mPopup.setBackgroundDrawable(getResources().getDrawable(id));
+        mPopup.setBackgroundDrawable(getContext().getDrawable(id));
     }
     
     /**
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index c6be6dd..ea60abb 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1029,7 +1029,7 @@
 
         @Override
         public void setSelectedDateVerticalBar(int resourceId) {
-            Drawable drawable = mDelegator.getResources().getDrawable(resourceId);
+            Drawable drawable = mDelegator.getContext().getDrawable(resourceId);
             setSelectedDateVerticalBar(drawable);
         }
 
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 78b1b75..1533510 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -123,7 +123,7 @@
 
         Drawable d = null;
         if (mCheckMarkResource != 0) {
-            d = getResources().getDrawable(mCheckMarkResource);
+            d = getContext().getDrawable(mCheckMarkResource);
         }
         setCheckMarkDrawable(d);
     }
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index b22088c..4298545 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -186,7 +186,7 @@
 
         Drawable d = null;
         if (mButtonResource != 0) {
-            d = getResources().getDrawable(mButtonResource);
+            d = getContext().getDrawable(mButtonResource);
         }
         setButtonDrawable(d);
     }
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 30752e0..fa37443 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -136,8 +136,8 @@
      */
     public EdgeEffect(Context context) {
         final Resources res = context.getResources();
-        mEdge = res.getDrawable(R.drawable.overscroll_edge);
-        mGlow = res.getDrawable(R.drawable.overscroll_glow);
+        mEdge = context.getDrawable(R.drawable.overscroll_edge);
+        mGlow = context.getDrawable(R.drawable.overscroll_glow);
 
         mEdgeHeight = mEdge.getIntrinsicHeight();
         mGlowHeight = mGlow.getIntrinsicHeight();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 11dbce8..ea62bbe 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1679,7 +1679,7 @@
 
     private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
         if (mCursorDrawable[cursorIndex] == null)
-            mCursorDrawable[cursorIndex] = mTextView.getResources().getDrawable(
+            mCursorDrawable[cursorIndex] = mTextView.getContext().getDrawable(
                     mTextView.mCursorDrawableRes);
 
         if (mTempRect == null) mTempRect = new Rect();
@@ -2969,7 +2969,7 @@
                 positionY += mContentView.getMeasuredHeight();
 
                 // Assumes insertion and selection handles share the same height
-                final Drawable handle = mTextView.getResources().getDrawable(
+                final Drawable handle = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRes);
                 positionY += handle.getIntrinsicHeight();
             }
@@ -3546,7 +3546,7 @@
 
         private InsertionHandleView getHandle() {
             if (mSelectHandleCenter == null) {
-                mSelectHandleCenter = mTextView.getResources().getDrawable(
+                mSelectHandleCenter = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRes);
             }
             if (mHandle == null) {
@@ -3592,11 +3592,11 @@
 
         private void initDrawables() {
             if (mSelectHandleLeft == null) {
-                mSelectHandleLeft = mTextView.getContext().getResources().getDrawable(
+                mSelectHandleLeft = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleLeftRes);
             }
             if (mSelectHandleRight == null) {
-                mSelectHandleRight = mTextView.getContext().getResources().getDrawable(
+                mSelectHandleRight = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRightRes);
             }
         }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 58e4e86..572302a4 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -642,7 +642,7 @@
 
         if (mResource != 0) {
             try {
-                d = rsrc.getDrawable(mResource);
+                d = mContext.getDrawable(mResource);
             } catch (Exception e) {
                 Log.w("ImageView", "Unable to find resource: " + mResource, e);
                 // Don't try again.
@@ -655,7 +655,7 @@
                     // Load drawable through Resources, to get the source density information
                     ContentResolver.OpenResourceIdResult r =
                             mContext.getContentResolver().getResourceId(mUri);
-                    d = r.r.getDrawable(r.id);
+                    d = r.r.getDrawable(r.id, mContext.getTheme());
                 } catch (Exception e) {
                     Log.w("ImageView", "Unable to open content: " + mUri, e);
                 }
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index a4f758c..74b41c9 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -155,7 +155,7 @@
      */
     public void setImageToDefault() {
         if (mDefaultAvatar == null) {
-            mDefaultAvatar = getResources().getDrawable(R.drawable.ic_contact_picture);
+            mDefaultAvatar = mContext.getDrawable(R.drawable.ic_contact_picture);
         }
         setImageDrawable(mDefaultAvatar);
     }
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 3791258..1eedc5d 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1059,7 +1059,7 @@
 
         SpannableStringBuilder ssb = new SpannableStringBuilder("   "); // for the icon
         ssb.append(hintText);
-        Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId());
+        Drawable searchIcon = getContext().getDrawable(getSearchIconId());
         int textSize = (int) (mQueryTextView.getTextSize() * 1.25);
         searchIcon.setBounds(0, 0, textSize, textSize);
         ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index bdaaa01..64a1574 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -168,7 +168,7 @@
         // Lookup and set the expand action icon.
         TypedValue outTypedValue = new TypedValue();
         mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
-        Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
+        Drawable drawable = mContext.getDrawable(outTypedValue.resourceId);
         activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
         activityChooserView.setProvider(this);
 
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index eabe1a3..9601d4a 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -281,7 +281,7 @@
      * @attr ref android.R.styleable#Spinner_popupBackground
      */
     public void setPopupBackgroundResource(int resId) {
-        setPopupBackgroundDrawable(getContext().getResources().getDrawable(resId));
+        setPopupBackgroundDrawable(getContext().getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index c44d431..c8917e0 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -529,7 +529,7 @@
                 return drawable;
             }
             // Not cached, find it by resource ID
-            drawable = mProviderContext.getResources().getDrawable(resourceId);
+            drawable = mProviderContext.getDrawable(resourceId);
             // Stick it in the cache, using the URI as key
             storeInIconCache(drawableUri, drawable);
             return drawable;
@@ -563,7 +563,7 @@
                 OpenResourceIdResult r =
                     mProviderContext.getContentResolver().getResourceId(uri);
                 try {
-                    return r.r.getDrawable(r.id);
+                    return r.r.getDrawable(r.id, mContext.getTheme());
                 } catch (Resources.NotFoundException ex) {
                     throw new FileNotFoundException("Resource does not exist: " + uri);
                 }
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index c9a1ca4..2a5fb15 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -417,7 +417,7 @@
      * @attr ref android.R.styleable#Switch_track
      */
     public void setTrackResource(int resId) {
-        setTrackDrawable(getContext().getResources().getDrawable(resId));
+        setTrackDrawable(getContext().getDrawable(resId));
     }
 
     /**
@@ -453,7 +453,7 @@
      * @attr ref android.R.styleable#Switch_thumb
      */
     public void setThumbResource(int resId) {
-        setThumbDrawable(getContext().getResources().getDrawable(resId));
+        setThumbDrawable(getContext().getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 568b3e6a..47a5449 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -120,28 +120,27 @@
         setChildrenDrawingOrderEnabled(true);
 
         final Context context = mContext;
-        final Resources resources = context.getResources();
 
         // Tests the target Sdk version, as set in the Manifest. Could not be set using styles.xml
         // in a values-v? directory which targets the current platform Sdk version instead.
         if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
             // Donut apps get old color scheme
             if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
+                mLeftStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_left_v4);
             }
             if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
+                mRightStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right_v4);
             }
         } else {
             // Use modern color scheme for Eclair and beyond
             if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
+                mLeftStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_left);
             }
             if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
+                mRightStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right);
             }
         }
@@ -246,7 +245,7 @@
      * divider.
      */
     public void setDividerDrawable(int resId) {
-        setDividerDrawable(getResources().getDrawable(resId));
+        setDividerDrawable(mContext.getDrawable(resId));
     }
     
     /**
@@ -267,7 +266,7 @@
      * left strip drawable
      */
     public void setLeftStripDrawable(int resId) {
-        setLeftStripDrawable(getResources().getDrawable(resId));
+        setLeftStripDrawable(mContext.getDrawable(resId));
     }
 
     /**
@@ -288,7 +287,7 @@
      * right strip drawable
      */
     public void setRightStripDrawable(int resId) {
-        setRightStripDrawable(getResources().getDrawable(resId));
+        setRightStripDrawable(mContext.getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 15606a45..3be23b7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2073,11 +2073,11 @@
      */
     @android.view.RemotableViewMethod
     public void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) {
-        final Resources resources = getContext().getResources();
-        setCompoundDrawablesWithIntrinsicBounds(left != 0 ? resources.getDrawable(left) : null,
-                top != 0 ? resources.getDrawable(top) : null,
-                right != 0 ? resources.getDrawable(right) : null,
-                bottom != 0 ? resources.getDrawable(bottom) : null);
+        final Context context = getContext();
+        setCompoundDrawablesWithIntrinsicBounds(left != 0 ? context.getDrawable(left) : null,
+                top != 0 ? context.getDrawable(top) : null,
+                right != 0 ? context.getDrawable(right) : null,
+                bottom != 0 ? context.getDrawable(bottom) : null);
     }
 
     /**
@@ -2247,12 +2247,12 @@
     @android.view.RemotableViewMethod
     public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end,
             int bottom) {
-        final Resources resources = getContext().getResources();
+        final Context context = getContext();
         setCompoundDrawablesRelativeWithIntrinsicBounds(
-                start != 0 ? resources.getDrawable(start) : null,
-                top != 0 ? resources.getDrawable(top) : null,
-                end != 0 ? resources.getDrawable(end) : null,
-                bottom != 0 ? resources.getDrawable(bottom) : null);
+                start != 0 ? context.getDrawable(start) : null,
+                top != 0 ? context.getDrawable(top) : null,
+                end != 0 ? context.getDrawable(end) : null,
+                bottom != 0 ? context.getDrawable(bottom) : null);
     }
 
     /**
@@ -4385,8 +4385,8 @@
         if (error == null) {
             setError(null, null);
         } else {
-            Drawable dr = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.indicator_input_error);
+            Drawable dr = getContext().getDrawable(
+                    com.android.internal.R.drawable.indicator_input_error);
 
             dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
             setError(error, dr);
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 347f957..0a80495 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -1081,7 +1081,7 @@
 
         @Override
         public Tab setIcon(int resId) {
-            return setIcon(mContext.getResources().getDrawable(resId));
+            return setIcon(mContext.getDrawable(resId));
         }
 
         @Override
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index 8fc99c7..b0e0373 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -256,13 +256,13 @@
     private Drawable getIconDrawable() {
         if (mRoute.isConnecting()) {
             if (mMediaRouteConnectingDrawable == null) {
-                mMediaRouteConnectingDrawable = getContext().getResources().getDrawable(
+                mMediaRouteConnectingDrawable = getContext().getDrawable(
                         R.drawable.ic_media_route_connecting_holo_dark);
             }
             return mMediaRouteConnectingDrawable;
         } else {
             if (mMediaRouteOnDrawable == null) {
-                mMediaRouteOnDrawable = getContext().getResources().getDrawable(
+                mMediaRouteOnDrawable = getContext().getDrawable(
                         R.drawable.ic_media_route_on_holo_dark);
             }
             return mMediaRouteOnDrawable;
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index 7ca6c1b..ed676bb 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -163,7 +163,7 @@
 
     public MenuItem setIcon(int iconRes) {
         mIconResId = iconRes;
-        mIconDrawable = mContext.getResources().getDrawable(iconRes);
+        mIconDrawable = mContext.getDrawable(iconRes);
         return this;
     }
 
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index b7cb0de..b776226 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -1121,7 +1121,7 @@
             }
             
             if (iconRes > 0) {
-                mHeaderIcon = r.getDrawable(iconRes);
+                mHeaderIcon = getContext().getDrawable(iconRes);
             } else if (icon != null) {
                 mHeaderIcon = icon;
             }
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 4d0a326..61dcaca 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -385,7 +385,7 @@
         }
 
         if (mIconResId != NO_ICON) {
-            Drawable icon =  mMenu.getResources().getDrawable(mIconResId);
+            Drawable icon =  mMenu.getContext().getDrawable(mIconResId);
             mIconResId = NO_ICON;
             mIconDrawable = icon;
             return icon;
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index ff2c625..1273c4d 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -697,7 +697,7 @@
     }
 
     public void setIcon(int resId) {
-        setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+        setIcon(resId != 0 ? mContext.getDrawable(resId) : null);
     }
 
     public boolean hasIcon() {
@@ -712,7 +712,7 @@
     }
 
     public void setLogo(int resId) {
-        setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+        setLogo(resId != 0 ? mContext.getDrawable(resId) : null);
     }
 
     public boolean hasLogo() {
@@ -1417,7 +1417,7 @@
 
         public void setUpIndicator(int resId) {
             mUpIndicatorRes = resId;
-            mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
+            mUpView.setImageDrawable(resId != 0 ? getContext().getDrawable(resId) : null);
         }
 
         @Override
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index 8368136..7483e75 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -72,8 +72,8 @@
 
     private void init(Context context) {
         final Resources res = context.getResources();
-        mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
-        mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
+        mShiftIcon = context.getDrawable(R.drawable.sym_keyboard_shift);
+        mShiftLockIcon = context.getDrawable(R.drawable.sym_keyboard_shift_locked);
         sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
                 R.dimen.password_keyboard_spacebar_vertical_correction);
     }
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index cd1ccd3..93ea5b3 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -234,7 +234,7 @@
         mMagneticTargets = a.getBoolean(R.styleable.GlowPadView_magneticTargets, mMagneticTargets);
 
         int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable);
-        Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null;
+        Drawable pointDrawable = pointId != 0 ? context.getDrawable(pointId) : null;
         mGlowRadius = a.getDimension(R.styleable.GlowPadView_glowRadius, 0.0f);
 
         TypedValue outValue = new TypedValue();
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 7b9b3fb..bcd4607 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -61,7 +61,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 8, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 4, 2014.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
@@ -92,7 +92,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 8, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 4, 2014.
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -133,17 +133,17 @@
 </tr>
 <tr>
 <td>2.0</th>
-<td>93.5%</td>
+<td>92.3%</td>
 </tr>
 <tr>
 <td>3.0</th>
-<td>6.4%</td>
+<td>7.6%</td>
 </tr>
 </table>
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on January 8, 2014</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on February 4, 2014</em></p>
 
 
 
@@ -161,7 +161,7 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chf=bg%2Cs%2C00000000&chd=t%3A1.3%2C21.2%2C0.1%2C16.9%2C59.1%2C1.4&chco=c4df9b%2C6fad0c&chs=500x250&cht=p",
+    "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chf=bg%2Cs%2C00000000&chd=t%3A1.3%2C20.0%2C0.1%2C16.1%2C60.7%2C1.8&chco=c4df9b%2C6fad0c",
     "data": [
       {
         "api": 8,
@@ -171,7 +171,7 @@
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "21.2"
+        "perc": "20.0"
       },
       {
         "api": 13,
@@ -181,27 +181,27 @@
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "16.9"
+        "perc": "16.1"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "35.9"
+        "perc": "35.5"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "15.4"
+        "perc": "16.3"
       },
       {
         "api": 18,
         "name": "Jelly Bean",
-        "perc": "7.8"
+        "perc": "8.9"
       },
       {
         "api": 19,
         "name": "KitKat",
-        "perc": "1.4"
+        "perc": "1.8"
       }
     ]
   }
@@ -217,30 +217,30 @@
     "data": {
       "Large": {
         "hdpi": "0.6",
-        "ldpi": "0.9",
-        "mdpi": "4.5",
-        "tvdpi": "1.7",
-        "xhdpi": "0.7"
+        "ldpi": "0.8",
+        "mdpi": "4.4",
+        "tvdpi": "1.6",
+        "xhdpi": "0.6"
       },
       "Normal": {
-        "hdpi": "33.0",
+        "hdpi": "33.3",
         "ldpi": "0.1",
-        "mdpi": "14.2",
-        "xhdpi": "20.1",
-        "xxhdpi": "10.6"
+        "mdpi": "13.9",
+        "xhdpi": "20.2",
+        "xxhdpi": "11.3"
       },
       "Small": {
-        "ldpi": "8.2"
+        "ldpi": "8.1"
       },
       "Xlarge": {
-        "hdpi": "0.4",
+        "hdpi": "0.3",
         "ldpi": "0.1",
-        "mdpi": "4.7",
+        "mdpi": "4.5",
         "xhdpi": "0.2"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A9.4%2C23.5%2C1.7%2C34.0%2C21.0%2C10.6&chco=c4df9b%2C6fad0c&chs=400x250&cht=p",
-    "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A5.4%2C8.5%2C78.0%2C8.2&chco=c4df9b%2C6fad0c&chs=400x250&cht=p"
+    "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A9.1%2C22.8%2C1.6%2C34.3%2C21.0%2C11.3&chco=c4df9b%2C6fad0c",
+    "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A5.1%2C8.0%2C78.9%2C8.1&chco=c4df9b%2C6fad0c"
   }
 ];
 
diff --git a/docs/html/google/play-services/setup.jd b/docs/html/google/play-services/setup.jd
index bf7fbe2..fb5daf8 100644
--- a/docs/html/google/play-services/setup.jd
+++ b/docs/html/google/play-services/setup.jd
@@ -92,7 +92,10 @@
 <p><b>Using Android Studio:</b></p>
 
 <ol>
-  <li>Open the <code>build.gradle</code> file inside your application directory.</li>
+  <li>Open the <code>build.gradle</code> file inside your application module directory. 
+      <p class="note"><strong>Note:</strong> Android Studio projects contain a top-level 
+      <code>build.gradle</code> file and a <code>build.gradle</code> file for each module. 
+      Be sure to edit the file for your application module.</p></li>
   <li>Add a new build rule under <code>dependencies</code> for the latest version of
 <code>play-services</code>. For example:
 <pre class="no-pretty-print">
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 1850123..f980042 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -27,6 +27,7 @@
   </li>
   <li><a href="#logcat">Enabling logcat logging</a></li>
   <li><a href="#stopping">Stopping the adb server</a></li>
+  <li><a href="#wireless">Wireless usage</a></li>
 </ol>
 
 </div>
@@ -1342,3 +1343,100 @@
 You can then restart the server by issuing any other adb command. </p>
 
 
+<h2 id="wireless">Wireless usage</h2>
+
+<p>
+adb is usually used over USB.  However, it is also possible to use over
+Wi-Fi, as described here.
+</p>
+
+<ol>
+
+<li>
+Connect Android device and adb host computer
+to a common Wi-Fi network accessible to both.
+We have found that not all access points
+are suitable; you may need to use an access point
+whose firewall is configured properly to support adb.
+</li>
+
+<li>
+Connect the device with USB cable to host.
+</li>
+
+<li>
+Make sure adb is running in USB mode on host.
+<pre>
+$ adb usb
+restarting in USB mode
+</pre>
+</li>
+
+<li>
+Connect to the device over USB.
+<pre>
+$ adb devices
+List of devices attached
+######## device
+</pre>
+</li>
+
+<li>
+Restart host adb in tcpip mode.
+<pre>
+$ adb tcpip 5555
+restarting in TCP mode port: 5555
+</pre>
+</li>
+
+<li>
+Find out the IP address of the Android device:
+Settings -> About tablet -> Status -> IP address.
+Remember the IP address, of the form <code>#.#.#.#</code>.
+</li>
+
+<li>
+Connect adb host to device:
+<pre>
+$ adb connect #.#.#.#
+connected to #.#.#.#:5555
+</pre>
+</li>
+
+<li>
+Remove USB cable from device, and confirm you can still access device:
+<pre>
+$ adb devices
+List of devices attached
+#.#.#.#:5555 device
+</pre>
+
+</ol>
+
+<p>
+You're now good to go!
+</p>
+
+<p>
+If the adb connection is ever lost:
+</p>
+
+<ol>
+
+<li>
+Make sure that your host is still connected to the same Wi-Fi network your Android device is.
+</li>
+
+<li>
+Reconnect by executing the "adb connect" step again.
+</li>
+
+<li>
+Or if that doesn't work, reset your adb host:
+<pre>
+adb kill-server
+</pre>
+and then start over from the beginning.
+</li>
+
+</ol>
diff --git a/docs/html/tools/samples/index.jd b/docs/html/tools/samples/index.jd
deleted file mode 100644
index a0d11e9..0000000
--- a/docs/html/tools/samples/index.jd
+++ /dev/null
@@ -1,32 +0,0 @@
-page.title=Samples
-page.tags=example,code
-@jd:body
-
-<p>To help you understand some fundamental Android APIs and coding practices, a variety of sample
-code is available from the Android SDK Manager. Each version of the Android platform available
-from the SDK Manager offers its own set of sample apps.</p>
-
-<p>To download the samples:</p>
-<ol>
-  <li>Launch the Android SDK Manager.
-    <ul>
-      <li>On Windows, double-click the SDK Manager.exe file at the root of the Android SDK
-directory.</li>
-      <li>On Mac or Linux, open a terminal to the {@code tools/} directory in the
-Android SDK, then execute {@code android sdk}.</ul>
-  </li>
-  <li>Expand the list of packages for the latest Android platform.</li>
-  <li>Select and download <em>Samples for SDK</em>.</li>
-</ol>
-
-<p>When the download is complete, you can find the source code for all samples at this location:</p>
-
-<p style="margin-left:2em">
-<code>&lt;sdk&gt;/samples/android-&lt;version>/</code>
-</p>
-
-<p>The {@code &lt;version>} number corresponds to the platform's
-  <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level</a>.</p>
-
-<p>You can easily create new Android projects with the downloaded samples, modify them
-if you'd like, and then run them on an emulator or device.</p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 3e6b6d4..a8424e6 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -240,12 +240,6 @@
 
 
   <li class="nav-section">
-    <div class="nav-section-header empty"><a href="<?cs var:toroot
-?>tools/samples/index.html"><span class="en">Samples</span></a></div>
-  </li>
-
-
-  <li class="nav-section">
     <div class="nav-section-header">
     <a href="<?cs var:toroot ?>tools/adk/index.html">
       <span class="en">ADK</span></a>
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index aec3a4b..630dc2e 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -31,13 +31,14 @@
 import java.io.IOException;
 
 /**
- * <p>A Drawable that can rotate another Drawable based on the current level
- * value. The start and end angles of rotation can be controlled to map any
- * circular arc to the level values range.</p>
- *
- * <p>It can be defined in an XML file with the <code>&lt;rotate></code> element. For more
- * information, see the guide to <a
- * href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+ * <p>
+ * A Drawable that can rotate another Drawable based on the current level value.
+ * The start and end angles of rotation can be controlled to map any circular
+ * arc to the level values range.
+ * <p>
+ * It can be defined in an XML file with the <code>&lt;rotate&gt;</code> element.
+ * For more information, see the guide to
+ * <a href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.
  *
  * @attr ref android.R.styleable#RotateDrawable_visible
  * @attr ref android.R.styleable#RotateDrawable_fromDegrees
@@ -49,20 +50,21 @@
 public class RotateDrawable extends Drawable implements Drawable.Callback {
     private static final float MAX_LEVEL = 10000.0f;
 
-    private RotateState mState;
+    private final RotateState mState;
+
     private boolean mMutated;
 
     /**
-     * <p>Create a new rotating drawable with an empty state.</p>
+     * Create a new rotating drawable with an empty state.
      */
     public RotateDrawable() {
         this(null, null);
     }
 
     /**
-     * <p>Create a new rotating drawable with the specified state. A copy of
+     * Create a new rotating drawable with the specified state. A copy of
      * this state is used as the internal state for the newly created
-     * drawable.</p>
+     * drawable.
      *
      * @param rotateState the state for this drawable
      */
@@ -70,28 +72,42 @@
         mState = new RotateState(rotateState, this, res);
     }
 
+    @Override
     public void draw(Canvas canvas) {
-        int saveCount = canvas.save();
-
-        Rect bounds = mState.mDrawable.getBounds();
-
-        int w = bounds.right - bounds.left;
-        int h = bounds.bottom - bounds.top;
-
         final RotateState st = mState;
-        
-        float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
-        float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
+        final Drawable d = st.mDrawable;
+        final Rect bounds = d.getBounds();
+        final int w = bounds.right - bounds.left;
+        final int h = bounds.bottom - bounds.top;
+        final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
+        final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
 
+        final int saveCount = canvas.save();
         canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
-
-        st.mDrawable.draw(canvas);
-
+        d.draw(canvas);
         canvas.restoreToCount(saveCount);
     }
 
     /**
-     * Returns the drawable rotated by this RotateDrawable.
+     * Sets the drawable rotated by this RotateDrawable.
+     *
+     * @param drawable The drawable to rotate
+     */
+    public void setDrawable(Drawable drawable) {
+        final Drawable oldDrawable = mState.mDrawable;
+        if (oldDrawable != drawable) {
+            if (oldDrawable != null) {
+                oldDrawable.setCallback(null);
+            }
+            mState.mDrawable = drawable;
+            if (drawable != null) {
+                drawable.setCallback(this);
+            }
+        }
+    }
+
+    /**
+     * @return The drawable rotated by this RotateDrawable
      */
     public Drawable getDrawable() {
         return mState.mDrawable;
@@ -103,7 +119,8 @@
                 | mState.mChangingConfigurations
                 | mState.mDrawable.getChangingConfigurations();
     }
-    
+
+    @Override
     public void setAlpha(int alpha) {
         mState.mDrawable.setAlpha(alpha);
     }
@@ -113,14 +130,149 @@
         return mState.mDrawable.getAlpha();
     }
 
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mState.mDrawable.setColorFilter(cf);
     }
 
+    @Override
     public int getOpacity() {
         return mState.mDrawable.getOpacity();
     }
 
+    /**
+     * Sets the start angle for rotation.
+     *
+     * @param fromDegrees Starting angle in degrees
+     */
+    public void setFromDegrees(float fromDegrees) {
+        if (mState.mFromDegrees != fromDegrees) {
+            mState.mFromDegrees = fromDegrees;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return The starting angle for rotation in degrees
+     */
+    public float getFromDegrees() {
+        return mState.mFromDegrees;
+    }
+
+    /**
+     * Sets the end angle for rotation.
+     *
+     * @param toDegrees Ending angle in degrees
+     */
+    public void setToDegrees(float toDegrees) {
+        if (mState.mToDegrees != toDegrees) {
+            mState.mToDegrees = toDegrees;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return The ending angle for rotation in degrees
+     */
+    public float getToDegrees() {
+        return mState.mToDegrees;
+    }
+
+    /**
+     * Sets the X position around which the drawable is rotated.
+     *
+     * @param pivotX X position around which to rotate. If the X pivot is
+     *            relative, the position represents a fraction of the drawable
+     *            width. Otherwise, the position represents an absolute value in
+     *            pixels.
+     * @see #setPivotXRelative(boolean)
+     */
+    public void setPivotX(float pivotX) {
+        if (mState.mPivotX == pivotX) {
+            mState.mPivotX = pivotX;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return X position around which to rotate
+     * @see #setPivotX(float)
+     */
+    public float getPivotX() {
+        return mState.mPivotX;
+    }
+
+    /**
+     * Sets whether the X pivot value represents a fraction of the drawable
+     * width or an absolute value in pixels.
+     *
+     * @param relative True if the X pivot represents a fraction of the drawable
+     *            width, or false if it represents an absolute value in pixels
+     */
+    public void setPivotXRelative(boolean relative) {
+        if (mState.mPivotXRel == relative) {
+            mState.mPivotXRel = relative;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return True if the X pivot represents a fraction of the drawable width,
+     *         or false if it represents an absolute value in pixels
+     * @see #setPivotXRelative(boolean)
+     */
+    public boolean isPivotXRelative() {
+        return mState.mPivotXRel;
+    }
+
+    /**
+     * Sets the Y position around which the drawable is rotated.
+     *
+     * @param pivotY Y position around which to rotate. If the Y pivot is
+     *            relative, the position represents a fraction of the drawable
+     *            height. Otherwise, the position represents an absolute value
+     *            in pixels.
+     * @see #setPivotYRelative(boolean)
+     */
+    public void setPivotY(float pivotY) {
+        if (mState.mPivotY == pivotY) {
+            mState.mPivotY = pivotY;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return Y position around which to rotate
+     * @see #setPivotY(float)
+     */
+    public float getPivotY() {
+        return mState.mPivotY;
+    }
+
+    /**
+     * Sets whether the Y pivot value represents a fraction of the drawable
+     * height or an absolute value in pixels.
+     *
+     * @param relative True if the Y pivot represents a fraction of the drawable
+     *            height, or false if it represents an absolute value in pixels
+     */
+    public void setPivotYRelative(boolean relative) {
+        if (mState.mPivotYRel == relative) {
+            mState.mPivotYRel = relative;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return True if the Y pivot represents a fraction of the drawable height,
+     *         or false if it represents an absolute value in pixels
+     * @see #setPivotYRelative(boolean)
+     */
+    public boolean isPivotYRelative() {
+        return mState.mPivotYRel;
+    }
+
+    @Override
     public void invalidateDrawable(Drawable who) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -128,6 +280,7 @@
         }
     }
 
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -135,6 +288,7 @@
         }
     }
 
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -157,10 +311,10 @@
     public boolean isStateful() {
         return mState.mDrawable.isStateful();
     }
-    
+
     @Override
     protected boolean onStateChange(int[] state) {
-        boolean changed = mState.mDrawable.setState(state);
+        final boolean changed = mState.mDrawable.setState(state);
         onBoundsChange(getBounds());
         return changed;
     }
@@ -172,7 +326,7 @@
 
         mState.mCurrentDegrees = mState.mFromDegrees +
                 (mState.mToDegrees - mState.mFromDegrees) *
-                        ((float) level / MAX_LEVEL);
+                        (level / MAX_LEVEL);
 
         invalidateSelf();
         return true;
@@ -206,16 +360,15 @@
     @Override
     public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
             throws XmlPullParserException, IOException {
-
-        TypedArray a = r.obtainAttributes(attrs,
+        final TypedArray a = r.obtainAttributes(attrs,
                 com.android.internal.R.styleable.RotateDrawable);
 
         super.inflateWithAttributes(r, parser, a,
                 com.android.internal.R.styleable.RotateDrawable_visible);
-        
+
         TypedValue tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotX);
-        boolean pivotXRel;
-        float pivotX;
+        final boolean pivotXRel;
+        final float pivotX;
         if (tv == null) {
             pivotXRel = true;
             pivotX = 0.5f;
@@ -223,10 +376,10 @@
             pivotXRel = tv.type == TypedValue.TYPE_FRACTION;
             pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
         }
-        
+
         tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotY);
-        boolean pivotYRel;
-        float pivotY;
+        final boolean pivotYRel;
+        final float pivotY;
         if (tv == null) {
             pivotYRel = true;
             pivotY = 0.5f;
@@ -235,12 +388,12 @@
             pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
         }
 
-        float fromDegrees = a.getFloat(
+        final float fromDegrees = a.getFloat(
                 com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
-        float toDegrees = a.getFloat(
+        final float toDegrees = a.getFloat(
                 com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);
 
-        int res = a.getResourceId(
+        final int res = a.getResourceId(
                 com.android.internal.R.styleable.RotateDrawable_drawable, 0);
         Drawable drawable = null;
         if (res > 0) {
@@ -248,8 +401,8 @@
         }
 
         a.recycle();
-        
-        int outerDepth = parser.getDepth();
+
+        final int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
                (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -268,13 +421,15 @@
             Log.w("drawable", "No drawable specified for <rotate>");
         }
 
-        mState.mDrawable = drawable;
-        mState.mPivotXRel = pivotXRel;
-        mState.mPivotX = pivotX;
-        mState.mPivotYRel = pivotYRel;
-        mState.mPivotY = pivotY;
-        mState.mFromDegrees = mState.mCurrentDegrees = fromDegrees;
-        mState.mToDegrees = toDegrees;
+        final RotateState st = mState;
+        st.mDrawable = drawable;
+        st.mPivotXRel = pivotXRel;
+        st.mPivotX = pivotX;
+        st.mPivotYRel = pivotYRel;
+        st.mPivotY = pivotY;
+        st.mFromDegrees = fromDegrees;
+        st.mCurrentDegrees = fromDegrees;
+        st.mToDegrees = toDegrees;
 
         if (drawable != null) {
             drawable.setCallback(this);
@@ -291,15 +446,15 @@
     }
 
     /**
-     * <p>Represents the state of a rotation for a given drawable. The same
+     * Represents the state of a rotation for a given drawable. The same
      * rotate drawable can be invoked with different states to drive several
-     * rotations at the same time.</p>
+     * rotations at the same time.
      */
     final static class RotateState extends Drawable.ConstantState {
         Drawable mDrawable;
 
         int mChangingConfigurations;
-        
+
         boolean mPivotXRel;
         float mPivotX;
         boolean mPivotYRel;
@@ -311,7 +466,7 @@
         float mCurrentDegrees;
 
         private boolean mCanConstantState;
-        private boolean mCheckedConstantState;        
+        private boolean mCheckedConstantState;
 
         public RotateState(RotateState source, RotateDrawable owner, Resources res) {
             if (source != null) {
@@ -336,12 +491,12 @@
         public Drawable newDrawable() {
             return new RotateDrawable(this, null);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new RotateDrawable(this, res);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 7c0735b..f82ca22 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -591,7 +591,7 @@
                 icon.setImageDrawable(mIcon);
                 icon.setScaleType(ScaleType.CENTER_CROP);
             } else if (mIconResId != 0) {
-                icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
+                icon.setImageDrawable(context.getDrawable(mIconResId));
             }
             if (mMessage != null) {
                 messageView.setText(mMessage);
@@ -681,7 +681,7 @@
 
             boolean on = ((mState == State.On) || (mState == State.TurningOn));
             if (icon != null) {
-                icon.setImageDrawable(context.getResources().getDrawable(
+                icon.setImageDrawable(context.getDrawable(
                         (on ? mEnabledIconResId : mDisabledIconResid)));
                 icon.setEnabled(enabled);
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index d0abe9c..a0ea53c 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -704,7 +704,7 @@
                 // Otherwise, set the normal panel background
                 backgroundResId = st.background;
             }
-            st.decorView.setWindowBackground(getContext().getResources().getDrawable(
+            st.decorView.setWindowBackground(getContext().getDrawable(
                     backgroundResId));
 
             ViewParent shownPanelParent = st.shownPanelView.getParent();
@@ -1289,7 +1289,7 @@
             if (st.resid != resId) {
                 st.resid = resId;
                 st.uri = null;
-                st.local = getContext().getResources().getDrawable(resId);
+                st.local = getContext().getDrawable(resId);
                 updateDrawable(featureId, st, false);
             }
         } else {
@@ -2305,7 +2305,7 @@
                     if (mMenuBackground == null && mFeatureId < 0
                             && getAttributes().height
                             == WindowManager.LayoutParams.MATCH_PARENT) {
-                        mMenuBackground = getContext().getResources().getDrawable(
+                        mMenuBackground = getContext().getDrawable(
                                 com.android.internal.R.drawable.menu_background);
                     }
                     if (mMenuBackground != null) {
@@ -3122,12 +3122,12 @@
         if (getContainer() == null) {
             Drawable drawable = mBackgroundDrawable;
             if (mBackgroundResource != 0) {
-                drawable = getContext().getResources().getDrawable(mBackgroundResource);
+                drawable = getContext().getDrawable(mBackgroundResource);
             }
             mDecor.setWindowBackground(drawable);
             drawable = null;
             if (mFrameResource != 0) {
-                drawable = getContext().getResources().getDrawable(mFrameResource);
+                drawable = getContext().getDrawable(mFrameResource);
             }
             mDecor.setWindowFrame(drawable);
 
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index e412c27..6a3c506 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1631,9 +1631,18 @@
 // =========================================================================
 // =========================================================================
 
-status_t AaptGroup::addFile(const sp<AaptFile>& file)
+status_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate)
 {
-    if (mFiles.indexOfKey(file->getGroupEntry()) < 0) {
+    ssize_t index = mFiles.indexOfKey(file->getGroupEntry());
+    if (index >= 0 && overwriteDuplicate) {
+        fprintf(stderr, "warning: overwriting '%s' with '%s'\n",
+                mFiles[index]->getSourceFile().string(),
+                file->getSourceFile().string());
+        removeFile(index);
+        index = -1;
+    }
+
+    if (index < 0) {
         file->mPath = mPath;
         mFiles.add(file->getGroupEntry(), file);
         return NO_ERROR;
@@ -1739,7 +1748,8 @@
     mDirs.removeItem(name);
 }
 
-status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file)
+status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file,
+        const bool overwrite)
 {
     sp<AaptGroup> group;
     if (mFiles.indexOfKey(leafName) >= 0) {
@@ -1749,12 +1759,12 @@
         mFiles.add(leafName, group);
     }
 
-    return group->addFile(file);
+    return group->addFile(file, overwrite);
 }
 
 ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
                             const AaptGroupEntry& kind, const String8& resType,
-                            sp<FilePathStore>& fullResPaths)
+                            sp<FilePathStore>& fullResPaths, const bool overwrite)
 {
     Vector<String8> fileNames;
     {
@@ -1813,7 +1823,7 @@
                 notAdded = true;
             }
             ssize_t res = subdir->slurpFullTree(bundle, pathName, kind,
-                                                resType, fullResPaths);
+                                                resType, fullResPaths, overwrite);
             if (res < NO_ERROR) {
                 return res;
             }
@@ -1823,7 +1833,7 @@
             count += res;
         } else if (type == kFileTypeRegular) {
             sp<AaptFile> file = new AaptFile(pathName, kind, resType);
-            status_t err = addLeafFile(fileNames[i], file);
+            status_t err = addLeafFile(fileNames[i], file, overwrite);
             if (err != NO_ERROR) {
                 return err;
             }
@@ -2089,24 +2099,24 @@
     /*
      * If a directory of custom assets was supplied, slurp 'em up.
      */
-    if (bundle->getAssetSourceDir()) {
-        const char* assetDir = bundle->getAssetSourceDir();
-
-        FileType type = getFileType(assetDir);
+    const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs();
+    const int AN = assetDirs.size();
+    for (int i = 0; i < AN; i++) {
+        FileType type = getFileType(assetDirs[i]);
         if (type == kFileTypeNonexistent) {
-            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDir);
+            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDirs[i]);
             return UNKNOWN_ERROR;
         }
         if (type != kFileTypeDirectory) {
-            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir);
+            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDirs[i]);
             return UNKNOWN_ERROR;
         }
 
-        String8 assetRoot(assetDir);
+        String8 assetRoot(assetDirs[i]);
         sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));
         AaptGroupEntry group;
         count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,
-                                            String8(), mFullAssetPaths);
+                                            String8(), mFullAssetPaths, true);
         if (count < 0) {
             totalCount = count;
             goto bail;
@@ -2116,9 +2126,10 @@
         }
         totalCount += count;
 
-        if (bundle->getVerbose())
+        if (bundle->getVerbose()) {
             printf("Found %d custom asset file%s in %s\n",
-                   count, (count==1) ? "" : "s", assetDir);
+                   count, (count==1) ? "" : "s", assetDirs[i]);
+        }
     }
 
     /*
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 5cfa913..9cc9007 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -235,7 +235,7 @@
     const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const
         { return mFiles; }
 
-    status_t addFile(const sp<AaptFile>& file);
+    status_t addFile(const sp<AaptFile>& file, const bool overwriteDuplicate=false);
     void removeFile(size_t index);
 
     void print(const String8& prefix) const;
@@ -301,12 +301,14 @@
     status_t addDir(const String8& name, const sp<AaptDir>& dir);
     sp<AaptDir> makeDir(const String8& name);
     status_t addLeafFile(const String8& leafName,
-                         const sp<AaptFile>& file);
+                         const sp<AaptFile>& file,
+                         const bool overwrite=false);
     virtual ssize_t slurpFullTree(Bundle* bundle,
                                   const String8& srcDir,
                                   const AaptGroupEntry& kind,
                                   const String8& resType,
-                                  sp<FilePathStore>& fullResPaths);
+                                  sp<FilePathStore>& fullResPaths,
+                                  const bool overwrite=false);
 
     String8 mLeaf;
     String8 mPath;
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 52d9266..cbeaae8 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -55,7 +55,6 @@
           mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
           mAutoAddOverlay(false), mGenDependencies(false),
-          mAssetSourceDir(NULL),
           mCrunchedOutputDir(NULL), mProguardFile(NULL),
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
@@ -128,8 +127,8 @@
     /*
      * Input options.
      */
-    const char* getAssetSourceDir() const { return mAssetSourceDir; }
-    void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; }
+    const android::Vector<const char*>& getAssetSourceDirs() const { return mAssetSourceDirs; }
+    void addAssetSourceDir(const char* dir) { mAssetSourceDirs.insertAt(dir,0); }
     const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }
     void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }
     const char* getProguardFile() const { return mProguardFile; }
@@ -266,7 +265,6 @@
     const char* mInstrumentationPackageNameOverride;
     bool        mAutoAddOverlay;
     bool        mGenDependencies;
-    const char* mAssetSourceDir;
     const char* mCrunchedOutputDir;
     const char* mProguardFile;
     const char* mAndroidManifestFile;
@@ -278,6 +276,7 @@
     android::Vector<const char*> mPackageIncludes;
     android::Vector<const char*> mJarFiles;
     android::Vector<const char*> mNoCompressExtensions;
+    android::Vector<const char*> mAssetSourceDirs;
     android::Vector<const char*> mResourceSourceDirs;
 
     const char* mManifestMinSdkVersion;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index c527388..48e3125 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -2034,7 +2034,7 @@
 
     N = bundle->getFileSpecCount();
     if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0
-            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) {
+            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) {
         fprintf(stderr, "ERROR: no input files\n");
         goto bail;
     }
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 51a1248..1ed4630 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -349,7 +349,7 @@
                     goto bail;
                 }
                 convertPath(argv[0]);
-                bundle.setAssetSourceDir(argv[0]);
+                bundle.addAssetSourceDir(argv[0]);
                 break;
             case 'G':
                 argc--;