Merge "Fix issues around process teardown after full-data restore" into mnc-dev
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index dd3d3a8..9394d2c 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -321,6 +321,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that owns the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param account The account to query for a password. Must not be {@code null}.
      * @return The account's password, null if none or if the account doesn't exist
      */
@@ -345,6 +349,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that owns the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs
+     * for this function in API level 22.
+     *
      * @param account The account to query for user data
      * @return The user data, null if the account or key doesn't exist
      */
@@ -493,6 +501,10 @@
      * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
      * authenticator that owns the account type.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
+     * or signature match. See docs for this function in API level 22.
+     *
      * @param type The type of accounts to return, null to retrieve all accounts
      * @return An array of {@link Account}, one per matching account.  Empty
      *     (never null) if no accounts of the specified type have been added.
@@ -623,6 +635,11 @@
      * @param type The type of accounts to return, must not be null
      * @param features An array of the account features to require,
      *     may be null or empty
+     *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
+     * or signature match. See docs for this function in API level 22.
+     *
      * @param callback Callback to invoke when the request completes,
      *     null for no callback
      * @param handler {@link Handler} identifying the callback thread,
@@ -668,6 +685,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that owns the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs
+     * for this function in API level 22.
+     *
      * @param account The {@link Account} to add
      * @param password The password to associate with the account, null for none
      * @param userdata String values to use for the account's userdata, null for
@@ -720,6 +741,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
+     * is needed for those platforms. See docs for this function in API level 22.
+     *
      * @param account The {@link Account} to rename
      * @param newName String name to be associated with the account.
      * @param callback Callback to invoke when the request completes, null for
@@ -784,6 +809,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param account The {@link Account} to remove
      * @param callback Callback to invoke when the request completes,
      *     null for no callback
@@ -826,6 +855,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param account The {@link Account} to remove
      * @param activity The {@link Activity} context to use for launching a new
      *     authenticator-defined sub-Activity to prompt the user to delete an
@@ -919,6 +952,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
+     * is needed for those platforms. See docs for this function in API level 22.
+     *
      * @param account The {@link Account} to delete.
      * @return True if the account was successfully deleted, false if the
      *         account did not exist, the account is null, or another error
@@ -943,6 +980,10 @@
      *
      * <p>It is safe to call this method from the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS or USE_CREDENTIALS permission is needed for those
+     * platforms. See docs for this function in API level 22.
+     *
      * @param accountType The account type of the auth token to invalidate, must not be null
      * @param authToken The auth token to invalidate, may be null
      */
@@ -969,6 +1010,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
+     * is needed for those platforms. See docs for this function in API level 22.
+     *
      * @param account The account for which an auth token is to be fetched. Cannot be {@code null}.
      * @param authTokenType The type of auth token to fetch. Cannot be {@code null}. 
      * @return The cached auth token for this account and type, or null if
@@ -998,6 +1043,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
+     * is needed for those platforms. See docs for this function in API level 22.
+     *
      * @param account The account whose password is to be set. Cannot be
      *            {@code null}.
      * @param password The password to set, null to clear the password
@@ -1025,6 +1074,10 @@
      *
      * <p>It is safe to call this method from the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param account The account whose password to clear
      */
     public void clearPassword(final Account account) {
@@ -1047,6 +1100,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
+     * is needed for those platforms. See docs for this function in API level 22.
+     *
      * @param account Account whose user data is to be set. Must not be {@code null}.
      * @param key String user data key to set.  Must not be null
      * @param value String value to set, {@code null} to clear this user data key
@@ -1073,6 +1130,10 @@
      * <p>This method requires the caller to have a signature match with the
      * authenticator that manages the specified account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator
+     * is needed for those platforms. See docs for this function in API level 22.
+     *
      * @param account The account to set an auth token for
      * @param authTokenType The type of the auth token, see {#getAuthToken}
      * @param authToken The auth token to add to the cache
@@ -1095,6 +1156,10 @@
      * <p>This method may block while a network request completes, and must
      * never be made from the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * USE_CREDENTIALS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param account The account to fetch an auth token for
      * @param authTokenType The auth token type, see {@link #getAuthToken getAuthToken()}
      * @param notifyAuthFailure If true, display a notification and return null
@@ -1143,6 +1208,10 @@
      * access different functionality -- for example, Google uses different auth
      * tokens to access Gmail and Google Calendar for the same account.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * USE_CREDENTIALS permission is needed for those platforms. See docs for 
+     * this function in API level 22.
+     *
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
@@ -1306,6 +1375,10 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * USE_CREDENTIALS permission is needed for those platforms. See docs for 
+     * this function in API level 22.
+     *
      * @param account The account to fetch an auth token for
      * @param authTokenType The auth token type, an authenticator-dependent
      *     string token, must not be null
@@ -1369,6 +1442,10 @@
      *
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
+     * 
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
      *
      * @param accountType The type of account to add; must not be null
      * @param authTokenType The type of auth token (see {@link #getAuthToken})
@@ -1551,6 +1628,10 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs
+     * for this function in API level 22.
+     *
      * @param account The account to confirm password knowledge for
      * @param options Authenticator-specific options for the request;
      *     if the {@link #KEY_PASSWORD} string field is present, the
@@ -1629,6 +1710,10 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param account The account to update credentials for
      * @param authTokenType The credentials entered must allow an auth token
      *     of this type to be created (but no actual auth token is returned);
@@ -1689,6 +1774,10 @@
      * <p>This method requires the caller to have the same signature as the
      * authenticator associated with the specified account type.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs
+     * for this function in API level 22.
+     *
      * @param accountType The account type associated with the authenticator
      *     to adjust
      * @param activity The {@link Activity} context to use for launching a new
@@ -2209,6 +2298,10 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
+     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
+     * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
+     * this function in API level 22.
+     *
      * @param accountType The account type required
      *     (see {@link #getAccountsByType}), must not be null
      * @param authTokenType The desired auth token type
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fc71783..f3f2428 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -930,9 +930,9 @@
         private Action(Parcel in) {
             if (in.readInt() != 0) {
                 mIcon = Icon.CREATOR.createFromParcel(in);
-            }
-            if (mIcon.getType() == Icon.TYPE_RESOURCE) {
-                icon = mIcon.getResId();
+                if (mIcon.getType() == Icon.TYPE_RESOURCE) {
+                    icon = mIcon.getResId();
+                }
             }
             title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
             if (in.readInt() == 1) {
@@ -3174,7 +3174,8 @@
             RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(),
                     tombstone ? getActionTombstoneLayoutResource()
                               : getActionLayoutResource());
-            button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
+            final Icon ai = action.getIcon();
+            button.setTextViewCompoundDrawablesRelative(R.id.action0, ai, null, null, null);
             button.setTextViewText(R.id.action0, processLegacyText(action.title));
             if (!tombstone) {
                 button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
@@ -3193,7 +3194,7 @@
         }
 
         private void processLegacyAction(Action action, RemoteViews button) {
-            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, action.icon)) {
+            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, action.getIcon())) {
                 button.setTextViewCompoundDrawablesRelativeColorFilter(R.id.action0, 0,
                         mContext.getColor(R.color.notification_action_color_filter),
                         PorterDuff.Mode.MULTIPLY);
@@ -3608,7 +3609,6 @@
             mContentText = extras.getCharSequence(EXTRA_TEXT);
             mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
             mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT);
-            mSmallIcon = extras.getParcelable(EXTRA_SMALL_ICON);
             mProgress = extras.getInt(EXTRA_PROGRESS);
             mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX);
             mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
@@ -4442,7 +4442,7 @@
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new BuilderRemoteViews(mBuilder.mContext.getApplicationInfo(),
                     R.layout.notification_material_media_action);
-            button.setImageViewResource(R.id.action0, action.icon);
+            button.setImageViewIcon(R.id.action0, action.getIcon());
             button.setDrawableParameters(R.id.action0, false, -1,
                     0xFFFFFFFF,
                     PorterDuff.Mode.SRC_ATOP, -1);
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 0eda692..2cab914 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -17,6 +17,9 @@
 package android.service.notification;
 
 import android.app.Notification;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
@@ -40,6 +43,7 @@
     private final long postTime;
 
     private final int score;
+    private Context mContext; // used for inflation & icon expansion
 
     /** @hide */
     public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid,
@@ -261,4 +265,24 @@
     public String getGroupKey() {
         return groupKey;
     }
+
+    /**
+     * @hide
+     */
+    public Context getPackageContext(Context context) {
+        if (mContext == null) {
+            try {
+                ApplicationInfo ai = context.getPackageManager()
+                        .getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
+                mContext = context.createApplicationContext(ai,
+                        Context.CONTEXT_RESTRICTED);
+            } catch (PackageManager.NameNotFoundException e) {
+                mContext = null;
+            }
+        }
+        if (mContext == null) {
+            mContext = context;
+        }
+        return mContext;
+    }
 }
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 0b5824a..dcb2437 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -25,7 +25,6 @@
 import android.text.format.Time;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.widget.TextView;
 import android.widget.RemoteViews.RemoteView;
 
 import java.text.DateFormat;
@@ -228,14 +227,14 @@
             final boolean register = mAttachedViews.isEmpty();
             mAttachedViews.add(v);
             if (register) {
-                register(v.getContext().getApplicationContext());
+                register(getApplicationContextIfAvailable(v.getContext()));
             }
         }
 
         public void removeView(DateTimeView v) {
             mAttachedViews.remove(v);
             if (mAttachedViews.isEmpty()) {
-                unregister(v.getContext().getApplicationContext());
+                unregister(getApplicationContextIfAvailable(v.getContext()));
             }
         }
 
@@ -258,6 +257,11 @@
             return result;
         }
 
+        static final Context getApplicationContextIfAvailable(Context context) {
+            final Context ac = context.getApplicationContext();
+            return ac != null ? ac : context;
+        }
+
         void register(Context context) {
             final IntentFilter filter = new IntentFilter();
             filter.addAction(Intent.ACTION_TIME_TICK);
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 4b40501..47e894a 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -722,8 +722,10 @@
             LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
 
             totalWeight += lp.weight;
-            
-            if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
+
+            final boolean fillExcessSpace = lp.weight > 0;
+            final boolean hasZeroHeight = lp.height == 0;
+            if (heightMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroHeight) {
                 // Optimization: don't bother measuring children who are going to use
                 // leftover space. These views will get measured again down below if
                 // there is any leftover space.
@@ -731,12 +733,12 @@
                 mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
                 skippedMeasure = true;
             } else {
-                final boolean fillExcessSpace = lp.height == 0 && lp.weight > 0;
-                if (fillExcessSpace) {
-                    // heightMode is either UNSPECIFIED or AT_MOST, and this
-                    // child wanted to stretch to fill available space.
-                    // Translate that to WRAP_CONTENT so that it does not end up
-                    // with a height of 0.
+                if (fillExcessSpace && hasZeroHeight) {
+                    // The LinearLayout's heightMode is either UNSPECIFIED or
+                    // AT_MOST, and this child wanted to stretch to fill
+                    // available space. Translate the explicit height of 0 to
+                    // WRAP_CONTENT so that we can measure the view's ideal
+                    // height.
                     lp.height = LayoutParams.WRAP_CONTENT;
                 }
 
@@ -751,7 +753,11 @@
                 final int childHeight = child.getMeasuredHeight();
                 if (fillExcessSpace) {
                     usedExcessSpace += childHeight;
-                    lp.height = 0;
+
+                    // Restore original layout height.
+                    if (hasZeroHeight) {
+                        lp.height = 0;
+                    }
                 }
 
                 final int totalLength = mTotalLength;
@@ -1047,8 +1053,10 @@
                     child.getLayoutParams();
 
             totalWeight += lp.weight;
-            
-            if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
+
+            final boolean fillExcessSpace = lp.weight > 0;
+            final boolean hasZeroWidth = lp.width == 0;
+            if (widthMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroWidth) {
                 // Optimization: don't bother measuring children who are going to use
                 // leftover space. These views will get measured again down below if
                 // there is any leftover space.
@@ -1075,12 +1083,12 @@
                     skippedMeasure = true;
                 }
             } else {
-                final boolean fillExcessSpace = lp.width == 0 && lp.weight > 0;
-                if (fillExcessSpace) {
-                    // widthMode is either UNSPECIFIED or AT_MOST, and this
-                    // child wanted to stretch to fill available space.
-                    // Translate that to WRAP_CONTENT so that it does not end up
-                    // with a width of 0.
+                if (fillExcessSpace && hasZeroWidth) {
+                    // The LinearLayout's widthMode is either UNSPECIFIED or
+                    // AT_MOST, and this child wanted to stretch to fill
+                    // available space. Translate the explicit height of 0 to
+                    // WRAP_CONTENT so that we can measure the view's ideal
+                    // width.
                     lp.width = LayoutParams.WRAP_CONTENT;
                 }
 
@@ -1095,7 +1103,11 @@
                 final int childWidth = child.getMeasuredWidth();
                 if (fillExcessSpace) {
                     usedExcessSpace += childWidth;
-                    lp.width = 0;
+
+                    // Restore the original layout width.
+                    if (hasZeroWidth) {
+                        lp.width = 0;
+                    }
                 }
 
                 if (isExactly) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 74843ee..d158313 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1412,39 +1412,108 @@
         public TextViewDrawableAction(int viewId, boolean isRelative, int d1, int d2, int d3, int d4) {
             this.viewId = viewId;
             this.isRelative = isRelative;
+            this.useIcons = false;
             this.d1 = d1;
             this.d2 = d2;
             this.d3 = d3;
             this.d4 = d4;
         }
 
+        public TextViewDrawableAction(int viewId, boolean isRelative,
+                Icon i1, Icon i2, Icon i3, Icon i4) {
+            this.viewId = viewId;
+            this.isRelative = isRelative;
+            this.useIcons = true;
+            this.i1 = i1;
+            this.i2 = i2;
+            this.i3 = i3;
+            this.i4 = i4;
+        }
+
         public TextViewDrawableAction(Parcel parcel) {
             viewId = parcel.readInt();
             isRelative = (parcel.readInt() != 0);
-            d1 = parcel.readInt();
-            d2 = parcel.readInt();
-            d3 = parcel.readInt();
-            d4 = parcel.readInt();
+            useIcons = (parcel.readInt() != 0);
+            if (useIcons) {
+                if (parcel.readInt() != 0) {
+                    i1 = Icon.CREATOR.createFromParcel(parcel);
+                }
+                if (parcel.readInt() != 0) {
+                    i2 = Icon.CREATOR.createFromParcel(parcel);
+                }
+                if (parcel.readInt() != 0) {
+                    i3 = Icon.CREATOR.createFromParcel(parcel);
+                }
+                if (parcel.readInt() != 0) {
+                    i4 = Icon.CREATOR.createFromParcel(parcel);
+                }
+            } else {
+                d1 = parcel.readInt();
+                d2 = parcel.readInt();
+                d3 = parcel.readInt();
+                d4 = parcel.readInt();
+            }
         }
 
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(TAG);
             dest.writeInt(viewId);
             dest.writeInt(isRelative ? 1 : 0);
-            dest.writeInt(d1);
-            dest.writeInt(d2);
-            dest.writeInt(d3);
-            dest.writeInt(d4);
+            dest.writeInt(useIcons ? 1 : 0);
+            if (useIcons) {
+                if (i1 != null) {
+                    dest.writeInt(1);
+                    i1.writeToParcel(dest, 0);
+                } else {
+                    dest.writeInt(0);
+                }
+                if (i2 != null) {
+                    dest.writeInt(1);
+                    i2.writeToParcel(dest, 0);
+                } else {
+                    dest.writeInt(0);
+                }
+                if (i3 != null) {
+                    dest.writeInt(1);
+                    i3.writeToParcel(dest, 0);
+                } else {
+                    dest.writeInt(0);
+                }
+                if (i4 != null) {
+                    dest.writeInt(1);
+                    i4.writeToParcel(dest, 0);
+                } else {
+                    dest.writeInt(0);
+                }
+            } else {
+                dest.writeInt(d1);
+                dest.writeInt(d2);
+                dest.writeInt(d3);
+                dest.writeInt(d4);
+            }
         }
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
             final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
-            if (isRelative) {
-                target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4);
+            if (useIcons) {
+                final Context ctx = target.getContext();
+                final Drawable id1 = i1 == null ? null : i1.loadDrawable(ctx);
+                final Drawable id2 = i2 == null ? null : i2.loadDrawable(ctx);
+                final Drawable id3 = i3 == null ? null : i3.loadDrawable(ctx);
+                final Drawable id4 = i4 == null ? null : i4.loadDrawable(ctx);
+                if (isRelative) {
+                    target.setCompoundDrawablesRelativeWithIntrinsicBounds(id1, id2, id3, id4);
+                } else {
+                    target.setCompoundDrawablesWithIntrinsicBounds(id1, id2, id3, id4);
+                }
             } else {
-                target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4);
+                if (isRelative) {
+                    target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4);
+                } else {
+                    target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4);
+                }
             }
         }
 
@@ -1453,7 +1522,9 @@
         }
 
         boolean isRelative = false;
+        boolean useIcons = false;
         int d1, d2, d3, d4;
+        Icon i1, i2, i3, i4;
 
         public final static int TAG = 11;
     }
@@ -2067,6 +2138,41 @@
     }
 
     /**
+     * Equivalent to calling {@link
+     * TextView#setCompoundDrawablesWithIntrinsicBounds(Drawable, Drawable, Drawable, Drawable)}
+     * using the drawables yielded by {@link Icon#loadDrawable(Context)}.
+     *
+     * @param viewId The id of the view whose text should change
+     * @param left an Icon to place to the left of the text, or 0
+     * @param top an Icon to place above the text, or 0
+     * @param right an Icon to place to the right of the text, or 0
+     * @param bottom an Icon to place below the text, or 0
+     *
+     * @hide
+     */
+    public void setTextViewCompoundDrawables(int viewId, Icon left, Icon top, Icon right, Icon bottom) {
+        addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom));
+    }
+
+    /**
+     * Equivalent to calling {@link
+     * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable, Drawable, Drawable, Drawable)}
+     * using the drawables yielded by {@link Icon#loadDrawable(Context)}.
+     *
+     * @param viewId The id of the view whose text should change
+     * @param start an Icon to place before the text (relative to the
+     * layout direction), or 0
+     * @param top an Icon to place above the text, or 0
+     * @param end an Icon to place after the text, or 0
+     * @param bottom an Icon to place below the text, or 0
+     *
+     * @hide
+     */
+    public void setTextViewCompoundDrawablesRelative(int viewId, Icon start, Icon top, Icon end, Icon bottom) {
+        addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom));
+    }
+
+    /**
      * Equivalent to calling ImageView.setImageResource
      *
      * @param viewId The id of the view whose drawable should change
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 131ba46..a1462c4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2270,6 +2270,7 @@
      * @attr ref android.R.styleable#TextView_drawableRight
      * @attr ref android.R.styleable#TextView_drawableBottom
      */
+    @android.view.RemotableViewMethod
     public void setCompoundDrawablesWithIntrinsicBounds(@Nullable Drawable left,
             @Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom) {
 
@@ -2302,6 +2303,7 @@
      * @attr ref android.R.styleable#TextView_drawableEnd
      * @attr ref android.R.styleable#TextView_drawableBottom
      */
+    @android.view.RemotableViewMethod
     public void setCompoundDrawablesRelative(@Nullable Drawable start, @Nullable Drawable top,
             @Nullable Drawable end, @Nullable Drawable bottom) {
         Drawables dr = mDrawables;
@@ -2472,6 +2474,7 @@
      * @attr ref android.R.styleable#TextView_drawableEnd
      * @attr ref android.R.styleable#TextView_drawableBottom
      */
+    @android.view.RemotableViewMethod
     public void setCompoundDrawablesRelativeWithIntrinsicBounds(@Nullable Drawable start,
             @Nullable Drawable top, @Nullable Drawable end, @Nullable Drawable bottom) {
 
diff --git a/core/res/res/values-land/dimens_material.xml b/core/res/res/values-land/dimens_material.xml
index 202f4a4..660210a 100644
--- a/core/res/res/values-land/dimens_material.xml
+++ b/core/res/res/values-land/dimens_material.xml
@@ -17,8 +17,6 @@
 
     <!-- Default height of an action bar. -->
     <dimen name="action_bar_default_height_material">48dp</dimen>
-    <!-- Default padding of an action bar. -->
-    <dimen name="action_bar_default_padding_material">0dp</dimen>
     <!-- Default text size for action bar title.-->
     <dimen name="text_size_title_material_toolbar">14dp</dimen>
     <!-- Default text size for action bar subtitle.-->
diff --git a/core/res/res/values-sw600dp/dimens_material.xml b/core/res/res/values-sw600dp/dimens_material.xml
index dffe8e7..3bbb352 100644
--- a/core/res/res/values-sw600dp/dimens_material.xml
+++ b/core/res/res/values-sw600dp/dimens_material.xml
@@ -21,13 +21,11 @@
     <dimen name="text_size_subtitle_material_toolbar">16dp</dimen>
     <!-- Default height of an action bar. -->
     <dimen name="action_bar_default_height_material">64dp</dimen>
-    <!-- Default padding of an action bar. -->
-    <dimen name="action_bar_default_padding_material">4dp</dimen>
     <!-- Default content inset of an action bar. -->
     <dimen name="action_bar_content_inset_material">24dp</dimen>
 
-    <!-- Padding to add to the start of the overflow action button. -->
-    <dimen name="action_bar_navigation_padding_start_material">8dp</dimen>
-    <!-- Padding to add to the end of the overflow action button. -->
-    <dimen name="action_bar_overflow_padding_end_material">18dp</dimen>
+    <!-- Default start padding of an action bar. -->
+    <dimen name="action_bar_default_padding_start_material">8dp</dimen>
+    <!-- Default end padding of an action bar. -->
+    <dimen name="action_bar_default_padding_end_material">8dp</dimen>
 </resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 558afa7..55bea9e 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -35,8 +35,10 @@
 
     <!-- Default height of an action bar. -->
     <dimen name="action_bar_default_height_material">56dp</dimen>
-    <!-- Default padding of an action bar. -->
-    <dimen name="action_bar_default_padding_material">4dp</dimen>
+    <!-- Default start padding of an action bar. -->
+    <dimen name="action_bar_default_padding_start_material">0dp</dimen>
+    <!-- Default end padding of an action bar. -->
+    <dimen name="action_bar_default_padding_end_material">0dp</dimen>
     <!-- Default content inset of an action bar. -->
     <dimen name="action_bar_content_inset_material">16dp</dimen>
     <!-- Vertical padding around action bar icons. -->
@@ -51,8 +53,6 @@
     <dimen name="list_item_padding_horizontal_material">@dimen/action_bar_content_inset_material</dimen>
 
     <!-- Padding to add to the start of the overflow action button. -->
-    <dimen name="action_bar_navigation_padding_start_material">0dp</dimen>
-    <!-- Padding to add to the start of the overflow action button. -->
     <dimen name="action_bar_overflow_padding_start_material">6dp</dimen>
     <!-- Padding to add to the end of the overflow action button. -->
     <dimen name="action_bar_overflow_padding_end_material">10dp</dimen>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 1b9c409..1e202e4 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -809,13 +809,14 @@
         <item name="navigationButtonStyle">@style/Widget.Material.Toolbar.Button.Navigation</item>
         <item name="titleTextAppearance">@style/TextAppearance.Material.Widget.Toolbar.Title</item>
         <item name="subtitleTextAppearance">@style/TextAppearance.Material.Widget.Toolbar.Subtitle</item>
+        <item name="paddingStart">@dimen/action_bar_default_padding_start_material</item>
+        <item name="paddingEnd">@dimen/action_bar_default_padding_end_material</item>
     </style>
 
     <style name="Widget.Material.Toolbar.Button.Navigation" parent="Widget.Material">
         <item name="background">@drawable/control_background_40dp_material</item>
         <item name="minWidth">56dp</item>
         <item name="scaleType">center</item>
-        <item name="paddingStart">@dimen/action_bar_navigation_padding_start_material</item>
     </style>
 
     <style name="Widget.Material.WebTextView" parent="Widget.WebTextView"/>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9df0818..c7adc98 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -380,9 +380,7 @@
 
     private void handleFingerprintAuthFailed() {
         releaseFingerprintWakeLock();
-        stopListeningForFingerprint();
         handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
-        updateFingerprintListeningState();
     }
 
     private void handleFingerprintAcquired(int acquireInfo) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 41b37b0..9c37263 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1328,14 +1328,20 @@
         View bigContentViewLocal = null;
         View headsUpContentViewLocal = null;
         try {
-            contentViewLocal = contentView.apply(mContext, contentContainer,
+            contentViewLocal = contentView.apply(
+                    sbn.getPackageContext(mContext),
+                    contentContainer,
                     mOnClickHandler);
             if (bigContentView != null) {
-                bigContentViewLocal = bigContentView.apply(mContext, contentContainer,
+                bigContentViewLocal = bigContentView.apply(
+                        sbn.getPackageContext(mContext),
+                        contentContainer,
                         mOnClickHandler);
             }
             if (headsUpContentView != null) {
-                headsUpContentViewLocal = headsUpContentView.apply(mContext, contentContainer,
+                headsUpContentViewLocal = headsUpContentView.apply(
+                        sbn.getPackageContext(mContext),
+                        contentContainer,
                         mOnClickHandler);
             }
         }
@@ -1362,7 +1368,8 @@
         View publicViewLocal = null;
         if (publicNotification != null) {
             try {
-                publicViewLocal = publicNotification.contentView.apply(mContext,
+                publicViewLocal = publicNotification.contentView.apply(
+                        sbn.getPackageContext(mContext),
                         contentContainerPublic, mOnClickHandler);
 
                 if (publicViewLocal != null) {
@@ -1981,15 +1988,18 @@
         // Reapply the RemoteViews
         contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
         if (bigContentView != null && entry.getExpandedContentView() != null) {
-            bigContentView.reapply(mContext, entry.getExpandedContentView(),
+            bigContentView.reapply(notification.getPackageContext(mContext),
+                    entry.getExpandedContentView(),
                     mOnClickHandler);
         }
         View headsUpChild = entry.getHeadsUpContentView();
         if (headsUpContentView != null && headsUpChild != null) {
-            headsUpContentView.reapply(mContext, headsUpChild, mOnClickHandler);
+            headsUpContentView.reapply(notification.getPackageContext(mContext),
+                    headsUpChild, mOnClickHandler);
         }
         if (publicContentView != null && entry.getPublicContentView() != null) {
-            publicContentView.reapply(mContext, entry.getPublicContentView(), mOnClickHandler);
+            publicContentView.reapply(notification.getPackageContext(mContext),
+                    entry.getPublicContentView(), mOnClickHandler);
         }
         // update the contentIntent
         mNotificationClicker.register(entry.row, notification);