Merge "Implement View.cancelDrag"
diff --git a/api/current.txt b/api/current.txt
index 429b117..1a7139c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4795,7 +4795,7 @@
     method public android.graphics.drawable.Icon getLargeIcon();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
-    method public android.app.Notification.Topic[] getTopics();
+    method public android.app.Notification.Topic getTopic();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -4960,7 +4960,6 @@
     method public android.app.Notification.Builder addAction(android.app.Notification.Action);
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Builder addPerson(java.lang.String);
-    method public android.app.Notification.Builder addTopic(android.app.Notification.Topic);
     method public android.app.Notification build();
     method public android.app.Notification.Builder extend(android.app.Notification.Extender);
     method public android.os.Bundle getExtras();
@@ -5009,6 +5008,7 @@
     method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
     method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
+    method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
     method public android.app.Notification.Builder setVisibility(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 6d53b3f..f2784410 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4913,7 +4913,7 @@
     method public android.graphics.drawable.Icon getLargeIcon();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
-    method public android.app.Notification.Topic[] getTopics();
+    method public android.app.Notification.Topic getTopic();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -5078,7 +5078,6 @@
     method public android.app.Notification.Builder addAction(android.app.Notification.Action);
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Builder addPerson(java.lang.String);
-    method public android.app.Notification.Builder addTopic(android.app.Notification.Topic);
     method public android.app.Notification build();
     method public android.app.Notification.Builder extend(android.app.Notification.Extender);
     method public android.os.Bundle getExtras();
@@ -5127,6 +5126,7 @@
     method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
     method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
+    method public android.app.Notification.Builder setTopic(android.app.Notification.Topic);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
     method public android.app.Notification.Builder setVisibility(int);
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 0745537..c0cc566 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -248,6 +248,7 @@
             } else if (mTransitioningViews != null) {
                 mTransitioningViews.addAll(mSharedElements);
             }
+            moveSharedElementsFromOverlay();
             mSharedElementNames.clear();
             mSharedElements.clear();
             mAllSharedElementNames.clear();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0b77be3..390c280 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1466,10 +1466,10 @@
                 };
     }
 
-    private Topic[] topics;
+    private Topic topic;
 
-    public Topic[] getTopics() {
-        return topics;
+    public Topic getTopic() {
+        return topic;
     }
 
     /**
@@ -1599,7 +1599,9 @@
 
         color = parcel.readInt();
 
-        topics = parcel.createTypedArray(Topic.CREATOR); // may be null
+        if (parcel.readInt() != 0) {
+            topic = Topic.CREATOR.createFromParcel(parcel);
+        }
     }
 
     @Override
@@ -1700,11 +1702,8 @@
 
         that.color = this.color;
 
-        if (this.topics != null) {
-            that.topics = new Topic[this.topics.length];
-            for(int i=0; i<this.topics.length; i++) {
-                that.topics[i] = this.topics[i].clone();
-            }
+        if (this.topic != null) {
+            that.topic = this.topic.clone();
         }
 
         if (!heavy) {
@@ -1878,7 +1877,12 @@
 
         parcel.writeInt(color);
 
-        parcel.writeTypedArray(topics, 0); // null ok
+        if (topic != null) {
+            parcel.writeInt(1);
+            topic.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
     }
 
     /**
@@ -2008,17 +2012,9 @@
             sb.append(" publicVersion=");
             sb.append(publicVersion.toString());
         }
-        if (topics != null) {
-            sb.append("topics=[");
-            int N = topics.length;
-            if (N > 0) {
-                for (int i = 0; i < N-1; i++) {
-                    sb.append(topics[i]);
-                    sb.append(',');
-                }
-                sb.append(topics[N-1]);
-            }
-            sb.append("]");
+        if (topic != null) {
+            sb.append("topic=");
+            sb.append(topic.toString());
         }
         sb.append(")");
         return sb.toString();
@@ -2136,7 +2132,6 @@
         private ArrayList<String> mPersonList = new ArrayList<String>();
         private NotificationColorUtil mColorUtil;
         private boolean mColorUtilInited = false;
-        private List<Topic> mTopics = new ArrayList<>();
 
         /**
          * The user that built the notification originally.
@@ -2187,10 +2182,6 @@
                     Collections.addAll(mPersonList, mN.extras.getStringArray(EXTRA_PEOPLE));
                 }
 
-                if (mN.getTopics() != null) {
-                    Collections.addAll(mTopics, mN.getTopics());
-                }
-
                 String templateClass = mN.extras.getString(EXTRA_TEMPLATE);
                 if (!TextUtils.isEmpty(templateClass)) {
                     final Class<? extends Style> styleClass
@@ -2962,15 +2953,15 @@
         }
 
         /**
-         * Add a topic to this notification. Topics are typically displayed in Notification
+         * Sets the topic of this notification. Topics are typically displayed in Notification
          * settings.
          * <p>
          * Every topic must have an id and a textual label.
          *
          * @param topic The topic to add.
          */
-        public Builder addTopic(Topic topic) {
-            mTopics.add(topic);
+        public Builder setTopic(Topic topic) {
+            mN.topic = topic;
             return this;
         }
 
@@ -3280,12 +3271,16 @@
          * Construct a RemoteViews for the final big notification layout.
          */
         public RemoteViews makeBigContentView() {
-            if (mStyle != null) {
+            if (mN.bigContentView != null) {
+                return mN.bigContentView;
+            } else if (mStyle != null) {
                 final RemoteViews styleView = mStyle.makeBigContentView();
                 if (styleView != null) {
                     return styleView;
                 }
-            } else if (mActions.size() == 0) return null;
+            } else if (mActions.size() == 0) {
+                return null;
+            }
 
             return applyStandardTemplateWithActions(getBigBaseLayoutResource());
         }
@@ -3294,12 +3289,17 @@
          * Construct a RemoteViews for the final heads-up notification layout.
          */
         public RemoteViews makeHeadsUpContentView() {
-            if (mStyle != null) {
-                final RemoteViews styleView = mStyle.makeHeadsUpContentView();
-                if (styleView != null) {
-                    return styleView;
-                }
-            } else if (mActions.size() == 0) return null;
+            if (mN.headsUpContentView != null) {
+                return mN.headsUpContentView;
+            } else if (mStyle != null) {
+                    final RemoteViews styleView = mStyle.makeHeadsUpContentView();
+                    if (styleView != null) {
+                        return styleView;
+                    }
+            } else if (mActions.size() == 0) {
+                return null;
+            }
+
 
             return applyStandardTemplateWithActions(getBigBaseLayoutResource());
         }
@@ -3452,10 +3452,6 @@
                 mN.extras.putStringArray(EXTRA_PEOPLE,
                         mPersonList.toArray(new String[mPersonList.size()]));
             }
-            if (mTopics.size() > 0) {
-                mN.topics = new Topic[mTopics.size()];
-                mTopics.toArray(mN.topics);
-            }
             return mN;
         }
 
diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java
index b627641..48359d47 100644
--- a/core/java/android/security/net/config/ApplicationConfig.java
+++ b/core/java/android/security/net/config/ApplicationConfig.java
@@ -144,4 +144,18 @@
             return sInstance;
         }
     }
+
+    /** @hide */
+    public static ApplicationConfig getPlatformDefault() {
+        return new ApplicationConfig(new ConfigSource() {
+            @Override
+            public NetworkSecurityConfig getDefaultConfig() {
+                return NetworkSecurityConfig.DEFAULT;
+            }
+            @Override
+            public Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs() {
+                return null;
+            }
+        });
+    }
 }
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 8906f9b..9eab80c 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -16,11 +16,14 @@
 
 package android.security.net.config;
 
+import android.util.ArrayMap;
 import android.util.ArraySet;
+import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.net.ssl.X509TrustManager;
@@ -57,12 +60,24 @@
             if (mAnchors != null) {
                 return mAnchors;
             }
-            Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>();
+            // Merge trust anchors based on the X509Certificate.
+            // If we see the same certificate in two TrustAnchors, one with overridesPins and one
+            // without, the one with overridesPins wins.
+            Map<X509Certificate, TrustAnchor> anchorMap = new ArrayMap<>();
             for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
-                anchors.addAll(ref.getTrustAnchors());
+                Set<TrustAnchor> anchors = ref.getTrustAnchors();
+                for (TrustAnchor anchor : anchors) {
+                    if (anchor.overridesPins) {
+                        anchorMap.put(anchor.certificate, anchor);
+                    } else if (!anchorMap.containsKey(anchor.certificate)) {
+                        anchorMap.put(anchor.certificate, anchor);
+                    }
+                }
             }
+            ArraySet<TrustAnchor> anchors = new ArraySet<TrustAnchor>(anchorMap.size());
+            anchors.addAll(anchorMap.values());
             mAnchors = anchors;
-            return anchors;
+            return mAnchors;
         }
     }
 
diff --git a/core/java/android/security/net/config/NetworkSecurityConfigProvider.java b/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
index ca8cdae..ac762ef 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
@@ -16,13 +16,21 @@
 
 package android.security.net.config;
 
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+import java.security.Security;
 import java.security.Provider;
 
 /** @hide */
 public final class NetworkSecurityConfigProvider extends Provider {
-
-    private static String PREFIX =
+    private static final String LOG_TAG = "NetworkSecurityConfig";
+    private static final String PREFIX =
             NetworkSecurityConfigProvider.class.getPackage().getName() + ".";
+    public static final String META_DATA_NETWORK_SECURITY_CONFIG =
+            "android.security.net.config";
+    private static final boolean DBG = true;
 
     public NetworkSecurityConfigProvider() {
         // TODO: More clever name than this
@@ -30,4 +38,43 @@
         put("TrustManagerFactory.PKIX", PREFIX + "RootTrustManagerFactorySpi");
         put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
     }
+
+    public static void install(Context context) {
+        ApplicationInfo info = null;
+        // TODO: This lookup shouldn't be done in the app startup path, it should be done lazily.
+        try {
+            info = context.getPackageManager().getApplicationInfo(context.getPackageName(),
+                    PackageManager.GET_META_DATA);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new RuntimeException("Failed to look up ApplicationInfo", e);
+        }
+        int configResourceId = 0;
+        if (info != null && info.metaData != null) {
+            configResourceId = info.metaData.getInt(META_DATA_NETWORK_SECURITY_CONFIG);
+        }
+
+        ApplicationConfig config;
+        if (configResourceId != 0) {
+            boolean debugBuild = (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+            if (DBG) {
+                Log.d(LOG_TAG, "Using Network Security Config from resource "
+                        + context.getResources().getResourceEntryName(configResourceId)
+                        + " debugBuild: " + debugBuild);
+            }
+            ConfigSource source = new XmlConfigSource(context, configResourceId, debugBuild);
+            config = new ApplicationConfig(source);
+        } else {
+            if (DBG) {
+                Log.d(LOG_TAG, "No Network Security Config specified, using platform default");
+            }
+            config = ApplicationConfig.getPlatformDefault();
+        }
+
+        ApplicationConfig.setDefaultInstance(config);
+        int pos = Security.insertProviderAt(new NetworkSecurityConfigProvider(), 1);
+        if (pos != 1) {
+            throw new RuntimeException("Failed to install provider as highest priority provider."
+                    + " Provider was installed at position " + pos);
+        }
+    }
 }
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index 463eb5b..ebe3f47 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -52,9 +52,21 @@
     }
 
     public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp, int userHandle)
-            throws PackageManager.NameNotFoundException, RemoteException {
-        this(pm, AppGlobals.getPackageManager().getServiceInfo(comp,
-                PackageManager.GET_META_DATA, userHandle));
+            throws PackageManager.NameNotFoundException {
+        this(pm, getServiceInfoOrThrow(comp, userHandle));
+    }
+
+    static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle)
+            throws PackageManager.NameNotFoundException {
+        try {
+            ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(comp,
+                    PackageManager.GET_META_DATA, userHandle);
+            if (si != null) {
+                return si;
+            }
+        } catch (RemoteException e) {
+        }
+        throw new PackageManager.NameNotFoundException(comp.toString());
     }
 
     public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index 88e9a95..b61706e 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -24,6 +24,7 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
+import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Parcel;
@@ -142,6 +143,10 @@
     private Bitmap mBitmap;
     private float mHotSpotX;
     private float mHotSpotY;
+    // The bitmaps for the additional frame of animated pointer icon. Note that the first frame
+    // will be stored in mBitmap.
+    private Bitmap mBitmapFrames[];
+    private int mDurationPerFrame;
 
     private PointerIcon(int style) {
         mStyle = style;
@@ -472,6 +477,36 @@
         } else {
             drawable = context.getDrawable(bitmapRes);
         }
+        if (drawable instanceof AnimationDrawable) {
+            // Extract animation frame bitmaps.
+            final AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
+            final int frames = animationDrawable.getNumberOfFrames();
+            drawable = animationDrawable.getFrame(0);
+            if (frames == 1) {
+                Log.w(TAG, "Animation icon with single frame -- simply treating the first "
+                        + "frame as a normal bitmap icon.");
+            } else {
+                // Assumes they have the exact duration.
+                mDurationPerFrame = animationDrawable.getDuration(0);
+                mBitmapFrames = new Bitmap[frames - 1];
+                final int width = drawable.getIntrinsicWidth();
+                final int height = drawable.getIntrinsicHeight();
+                for (int i = 1; i < frames; ++i) {
+                    Drawable drawableFrame = animationDrawable.getFrame(i);
+                    if (!(drawableFrame instanceof BitmapDrawable)) {
+                        throw new IllegalArgumentException("Frame of an animated pointer icon "
+                                + "must refer to a bitmap drawable.");
+                    }
+                    if (drawableFrame.getIntrinsicWidth() != width ||
+                        drawableFrame.getIntrinsicHeight() != height) {
+                        throw new IllegalArgumentException("The bitmap size of " + i + "-th frame "
+                                + "is different. All frames should have the exact same size and "
+                                + "share the same hotspot.");
+                    }
+                    mBitmapFrames[i - 1] = ((BitmapDrawable)drawableFrame).getBitmap();
+                }
+            }
+        }
         if (!(drawable instanceof BitmapDrawable)) {
             throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
                     + "refer to a bitmap drawable.");
@@ -509,8 +544,7 @@
             case STYLE_HELP:
                 return com.android.internal.R.styleable.Pointer_pointerIconHelp;
             case STYLE_WAIT:
-                // falls back to the default icon because no animation support.
-                return com.android.internal.R.styleable.Pointer_pointerIconArrow;
+                return com.android.internal.R.styleable.Pointer_pointerIconWait;
             case STYLE_CELL:
                 return com.android.internal.R.styleable.Pointer_pointerIconCell;
             case STYLE_CROSSHAIR:
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 122b83a..9428f44 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -23,6 +23,7 @@
 import com.android.internal.view.IInputMethodManager;
 import com.android.internal.view.IInputMethodSession;
 import com.android.internal.view.InputBindResult;
+import com.android.internal.view.InputMethodClient;
 
 import android.annotation.RequiresPermission;
 import android.content.Context;
@@ -440,8 +441,11 @@
                 }
                 case MSG_UNBIND: {
                     final int sequence = msg.arg1;
+                    @InputMethodClient.UnbindReason
+                    final int reason = msg.arg2;
                     if (DEBUG) {
-                        Log.i(TAG, "handleMessage: MSG_UNBIND " + sequence);
+                        Log.i(TAG, "handleMessage: MSG_UNBIND " + sequence +
+                                " reason=" + InputMethodClient.getUnbindReason(reason));
                     }
                     final boolean startInput;
                     synchronized (mH) {
@@ -569,8 +573,8 @@
         }
 
         @Override
-        public void onUnbindMethod(int sequence) {
-            mH.sendMessage(mH.obtainMessage(MSG_UNBIND, sequence, 0));
+        public void onUnbindMethod(int sequence, @InputMethodClient.UnbindReason int unbindReason) {
+            mH.sendMessage(mH.obtainMessage(MSG_UNBIND, sequence, unbindReason));
         }
 
         @Override
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 5eea252..47df4e8 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -177,8 +177,7 @@
 
     public void onConfigurationChanged(Configuration newConfig) {
         if (!mMaxItemsSet) {
-            mMaxItems = mContext.getResources().getInteger(
-                    com.android.internal.R.integer.max_action_buttons);
+            mMaxItems = ActionBarPolicy.get(mContext).getMaxActionButtons();
         }
         if (mMenu != null) {
             mMenu.onItemsChanged(true);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b5d994d..3e6d121 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3366,10 +3366,17 @@
     }
 
     /**
-     * Sets whether the movement method will automatically be set to
-     * {@link LinkMovementMethod} if {@link #setAutoLinkMask} has been
-     * set to nonzero and links are detected in {@link #setText}.
-     * The default is true.
+     * Sets whether the movement method will automatically be set to {@link LinkMovementMethod}
+     * after {@link #setText} or {@link #append} is called. The movement method is set if one of the
+     * following is true:
+     * <ul>
+     * <li>{@link #setAutoLinkMask} has been set to nonzero and links are detected in
+     * {@link #setText} or {@link #append}.
+     * <li>The input for {@link #setText} or {@link #append} contains a {@link ClickableSpan}.
+     * </ul>
+     *
+     * <p>This function does not have an immediate effect, movement method will be set only after a
+     * call to {@link #setText} or {@link #append}. The default is true.</p>
      *
      * @attr ref android.R.styleable#TextView_linksClickable
      */
@@ -3379,10 +3386,14 @@
     }
 
     /**
-     * Returns whether the movement method will automatically be set to
-     * {@link LinkMovementMethod} if {@link #setAutoLinkMask} has been
-     * set to nonzero and links are detected in {@link #setText}.
-     * The default is true.
+     * Returns whether the movement method will automatically be set to {@link LinkMovementMethod}
+     * after {@link #setText} or {@link #append} is called.
+     *
+     * See {@link #setLinksClickable} for details.
+     *
+     * <p>The default is true.</p>
+     *
+     * @see #setLinksClickable
      *
      * @attr ref android.R.styleable#TextView_linksClickable
      */
@@ -3976,13 +3987,19 @@
 
         ((Editable) mText).append(text, start, end);
 
+        boolean hasClickableSpans = false;
         if (mAutoLinkMask != 0) {
-            boolean linksWereAdded = Linkify.addLinks((Spannable) mText, mAutoLinkMask);
-            // Do not change the movement method for text that support text selection as it
-            // would prevent an arbitrary cursor displacement.
-            if (linksWereAdded && mLinksClickable && !textCanBeSelected()) {
-                setMovementMethod(LinkMovementMethod.getInstance());
-            }
+            hasClickableSpans = Linkify.addLinks((Spannable) mText, mAutoLinkMask);
+        } else if (mLinksClickable && text instanceof Spanned) {
+            ClickableSpan[] clickableSpans =
+                    ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class);
+            hasClickableSpans = clickableSpans != null && clickableSpans.length > 0;
+        }
+
+        // Do not change the movement method for text that supports text selection as it
+        // would prevent an arbitrary cursor displacement.
+        if (hasClickableSpans && mLinksClickable && !textCanBeSelected()) {
+            setMovementMethod(LinkMovementMethod.getInstance());
         }
     }
 
@@ -4327,6 +4344,7 @@
             text = TextUtils.stringOrSpannedString(text);
         }
 
+        boolean hasClickableSpans = false;
         if (mAutoLinkMask != 0) {
             Spannable s2;
 
@@ -4336,22 +4354,32 @@
                 s2 = mSpannableFactory.newSpannable(text);
             }
 
-            if (Linkify.addLinks(s2, mAutoLinkMask)) {
+            hasClickableSpans = Linkify.addLinks(s2, mAutoLinkMask);
+            if (hasClickableSpans) {
                 text = s2;
-                type = (type == BufferType.EDITABLE) ? BufferType.EDITABLE : BufferType.SPANNABLE;
+            }
+        } else if (mLinksClickable && text instanceof Spanned) {
+            ClickableSpan[] clickableSpans =
+                    ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class);
+            hasClickableSpans = clickableSpans != null && clickableSpans.length > 0;
+            if (hasClickableSpans && !(text instanceof Spannable)) {
+                text = mSpannableFactory.newSpannable(text);
+            }
+        }
 
-                /*
-                 * We must go ahead and set the text before changing the
-                 * movement method, because setMovementMethod() may call
-                 * setText() again to try to upgrade the buffer type.
-                 */
-                mText = text;
+        if (hasClickableSpans) {
+            type = (type == BufferType.EDITABLE) ? BufferType.EDITABLE : BufferType.SPANNABLE;
+            /*
+             * We must go ahead and set the text before changing the
+             * movement method, because setMovementMethod() may call
+             * setText() again to try to upgrade the buffer type.
+             */
+            mText = text;
 
-                // Do not change the movement method for text that support text selection as it
-                // would prevent an arbitrary cursor displacement.
-                if (mLinksClickable && !textCanBeSelected()) {
-                    setMovementMethod(LinkMovementMethod.getInstance());
-                }
+            // Do not change the movement method for text that supports text selection as it
+            // would prevent an arbitrary cursor displacement.
+            if (mLinksClickable && !textCanBeSelected()) {
+                setMovementMethod(LinkMovementMethod.getInstance());
             }
         }
 
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index 1eeb363..b101733 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.policy;
 
-import com.android.internal.widget.NonClientDecorView;
-
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Looper;
@@ -37,7 +35,7 @@
  */
 public class BackdropFrameRenderer extends Thread implements Choreographer.FrameCallback {
 
-    private NonClientDecorView mNonClientDecorView;
+    private DecorView mDecorView;
 
     // This is containing the last requested size by a resize command. Note that this size might
     // or might not have been applied to the output already.
@@ -62,12 +60,15 @@
     // Whether to report when next frame is drawn or not.
     private boolean mReportNextDraw;
 
-    public BackdropFrameRenderer(NonClientDecorView nonClientDecorView,
-            ThreadedRenderer renderer,
-            Rect initialBounds) {
-        mNonClientDecorView = nonClientDecorView;
+    private Drawable mCaptionBackgroundDrawable;
+    private Drawable mResizingBackgroundDrawable;
+
+    public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
+            Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable) {
         setName("ResizeFrame");
+
         mRenderer = renderer;
+        onResourcesLoaded(decorView, resizingBackgroundDrawable, captionBackgroundDrawable);
 
         // Create a render node for the content and frame backdrop
         // which can be resized independently from the content.
@@ -85,6 +86,13 @@
         start();
     }
 
+    void onResourcesLoaded(DecorView decorView, Drawable resizingBackgroundDrawable,
+            Drawable captionBackgroundDrawableDrawable) {
+        mDecorView = decorView;
+        mResizingBackgroundDrawable = resizingBackgroundDrawable;
+        mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
+    }
+
     /**
      * Call this function asynchronously when the window size has been changed. The change will
      * be picked up once per frame and the frame will be re-rendered accordingly.
@@ -201,7 +209,8 @@
                     mLastYOffset + mLastCaptionHeight + mLastContentHeight);
             // If this was the first call and changeWindowSizeLocked got already called prior
             // to us, we should re-issue a changeWindowSizeLocked now.
-            return firstCall && (mLastCaptionHeight != 0 || !mNonClientDecorView.mShowDecor);
+            return firstCall
+                    && (mLastCaptionHeight != 0 || !mDecorView.isShowingCaption());
         }
     }
 
@@ -218,25 +227,25 @@
      * @param newBounds The window bounds which needs to be drawn.
      */
     private void changeWindowSizeLocked(Rect newBounds) {
+
         // While a configuration change is taking place the view hierarchy might become
         // inaccessible. For that case we remember the previous metrics to avoid flashes.
         // Note that even when there is no visible caption, the caption child will exist.
-        View caption = mNonClientDecorView.getChildAt(0);
-        if (caption != null) {
-            final int captionHeight = caption.getHeight();
-            // The caption height will probably never dynamically change while we are resizing.
-            // Once set to something other then 0 it should be kept that way.
-            if (captionHeight != 0) {
-                // Remember the height of the caption.
-                mLastCaptionHeight = captionHeight;
-            }
+        final int captionHeight = mDecorView.getCaptionHeight();
+        // The caption height will probably never dynamically change while we are resizing.
+        // Once set to something other then 0 it should be kept that way.
+        if (captionHeight != 0) {
+            // Remember the height of the caption.
+            mLastCaptionHeight = captionHeight;
         }
+
         // Make sure that the other thread has already prepared the render draw calls for the
         // content. If any size is 0, we have to wait for it to be drawn first.
-        if ((mLastCaptionHeight == 0 && mNonClientDecorView.mShowDecor) ||
+        if ((mLastCaptionHeight == 0 && mDecorView.isShowingCaption()) ||
                 mLastContentWidth == 0 || mLastContentHeight == 0) {
             return;
         }
+
         // Since the surface is spanning the entire screen, we have to add the start offset of
         // the bounds to get to the surface location.
         final int left = mLastXOffset + newBounds.left;
@@ -247,15 +256,13 @@
         mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
 
         // Draw the caption and content backdrops in to our render node.
-        DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
-        mNonClientDecorView.mCaptionBackgroundDrawable.setBounds(
-                0, 0, left + width, top + mLastCaptionHeight);
-        mNonClientDecorView.mCaptionBackgroundDrawable.draw(canvas);
+        final DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
+        mCaptionBackgroundDrawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
+        mCaptionBackgroundDrawable.draw(canvas);
 
         // The backdrop: clear everything with the background. Clipping is done elsewhere.
-        mNonClientDecorView.mResizingBackgroundDrawable.setBounds(
-                0, mLastCaptionHeight, left + width, top + height);
-        mNonClientDecorView.mResizingBackgroundDrawable.draw(canvas);
+        mResizingBackgroundDrawable.setBounds(0, mLastCaptionHeight, left + width, top + height);
+        mResizingBackgroundDrawable.draw(canvas);
         mFrameAndBackdropNode.end(canvas);
 
         // We need to render the node explicitly
@@ -264,13 +271,11 @@
         reportDrawIfNeeded();
     }
 
-    /**
-     * Notify view root that a frame has been drawn by us, if it has requested so.
-     */
+    /** Notify view root that a frame has been drawn by us, if it has requested so. */
     private void reportDrawIfNeeded() {
         if (mReportNextDraw) {
-            if (mNonClientDecorView.isAttachedToWindow()) {
-                mNonClientDecorView.getViewRootImpl().reportDrawFinish();
+            if (mDecorView.isAttachedToWindow()) {
+                mDecorView.getViewRootImpl().reportDrawFinish();
             }
             mReportNextDraw = false;
         }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 49ceced..077cebc 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -52,11 +52,13 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
+import android.view.ThreadedRenderer;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewStub;
 import android.view.ViewTreeObserver;
 import android.view.Window;
+import android.view.WindowCallbacks;
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
@@ -80,7 +82,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
-class DecorView extends FrameLayout implements RootViewSurfaceTaker {
+/** @hide */
+public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
     private static final String TAG = "DecorView";
 
     private static final boolean SWEEP_OPEN_MENU = false;
@@ -167,6 +170,12 @@
     // workspace is expensive, this is the workspace value the window is currently set up for.
     int mWorkspaceId;
 
+    private boolean mWindowResizeCallbacksAdded = false;
+
+    public BackdropFrameRenderer mBackdropFrameRenderer = null;
+    private Drawable mResizingBackgroundDrawable;
+    private Drawable mCaptionBackgroundDrawable;
+
     DecorView(Context context, int featureId, PhoneWindow window) {
         super(context);
         mFeatureId = featureId;
@@ -1225,6 +1234,17 @@
              */
             mWindow.openPanelsAfterRestore();
         }
+
+        if (!mWindowResizeCallbacksAdded) {
+            // If there is no window callback installed there was no window set before. Set it now.
+            // Note that our ViewRootImpl object will not change.
+            getViewRootImpl().addWindowCallbacks(this);
+            mWindowResizeCallbacksAdded = true;
+        } else if (mBackdropFrameRenderer != null) {
+            // We are resizing and this call happened due to a configuration change. Tell the
+            // renderer about it.
+            mBackdropFrameRenderer.onConfigurationChange();
+        }
     }
 
     @Override
@@ -1256,6 +1276,11 @@
         if (st != null && st.menu != null && mFeatureId < 0) {
             st.menu.close();
         }
+
+        if (mWindowResizeCallbacksAdded) {
+            getViewRootImpl().removeWindowCallbacks(this);
+            mWindowResizeCallbacksAdded = false;
+        }
     }
 
     @Override
@@ -1526,6 +1551,18 @@
     }
 
     View onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
+        mWorkspaceId = getWorkspaceId();
+
+        mResizingBackgroundDrawable = getResizingBackgroundDrawable(
+                mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource);
+        mCaptionBackgroundDrawable =
+                getContext().getDrawable(R.drawable.non_client_decor_title_focused);
+
+        if (mBackdropFrameRenderer != null) {
+            mBackdropFrameRenderer.onResourcesLoaded(
+                    this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
+        }
+
         mNonClientDecorView = createNonClientDecorView(inflater);
         final View root = inflater.inflate(layoutResource, null);
         if (mNonClientDecorView != null) {
@@ -1556,12 +1593,10 @@
         final WindowManager.LayoutParams attrs = mWindow.getAttributes();
         boolean isApplication = attrs.type == TYPE_BASE_APPLICATION ||
                 attrs.type == TYPE_APPLICATION;
-        mWorkspaceId = getWorkspaceId();
         // Only a non floating application window on one of the allowed workspaces can get a non
         // client decor.
-        if (!mWindow.isFloating()
-                && isApplication
-                && ActivityManager.StackId.isStaticStack(mWorkspaceId)) {
+        final boolean hasNonClientDecor = ActivityManager.StackId.hasWindowDecor(mWorkspaceId);
+        if (!mWindow.isFloating() && isApplication && hasNonClientDecor) {
             // Dependent on the brightness of the used title we either use the
             // dark or the light button frame.
             if (nonClientDecorView == null) {
@@ -1579,34 +1614,32 @@
             }
             nonClientDecorView.setPhoneWindow(mWindow,
                     ActivityManager.StackId.hasWindowDecor(mWorkspaceId),
-                    ActivityManager.StackId.hasWindowShadow(mWorkspaceId),
-                    getResizingBackgroundDrawable(),
-                    getContext().getDrawable(R.drawable.non_client_decor_title_focused));
+                    ActivityManager.StackId.hasWindowShadow(mWorkspaceId));
+        } else {
+            nonClientDecorView = null;
         }
-        // Tell the decor if it has a visible non client decor.
-        enableNonClientDecor(
-                nonClientDecorView != null && ActivityManager.StackId.hasWindowDecor(mWorkspaceId));
 
+        // Tell the decor if it has a visible non client decor.
+        enableNonClientDecor(nonClientDecorView != null && hasNonClientDecor);
         return nonClientDecorView;
     }
 
     /**
-     * Returns the color used to fill areas the app has not rendered content to yet when the user
-     * is resizing the window of an activity in multi-window mode.
-     * */
-    private Drawable getResizingBackgroundDrawable() {
+     * Returns the color used to fill areas the app has not rendered content to yet when the
+     * user is resizing the window of an activity in multi-window mode.
+     */
+    private Drawable getResizingBackgroundDrawable(int backgroundRes, int backgroundFallbackRes) {
         final Context context = getContext();
 
-        if (mWindow.mBackgroundResource != 0) {
-            final Drawable drawable = context.getDrawable(mWindow.mBackgroundResource);
+        if (backgroundRes != 0) {
+            final Drawable drawable = context.getDrawable(backgroundRes);
             if (drawable != null) {
                 return drawable;
             }
         }
 
-        if (mWindow.mBackgroundFallbackResource != 0) {
-            final Drawable fallbackDrawable =
-                    context.getDrawable(mWindow.mBackgroundFallbackResource);
+        if (backgroundFallbackRes != 0) {
+            final Drawable fallbackDrawable = context.getDrawable(backgroundFallbackRes);
             if (fallbackDrawable != null) {
                 return fallbackDrawable;
             }
@@ -1652,6 +1685,84 @@
         }
     }
 
+    @Override
+    public void onWindowSizeIsChanging(Rect newBounds) {
+        if (mBackdropFrameRenderer != null) {
+            mBackdropFrameRenderer.setTargetRect(newBounds);
+        }
+    }
+
+    @Override
+    public void onWindowDragResizeStart(Rect initialBounds) {
+        if (mWindow.isDestroyed()) {
+            // If the owner's window is gone, we should not be able to come here anymore.
+            releaseThreadedRenderer();
+            return;
+        }
+        if (mBackdropFrameRenderer != null) {
+            return;
+        }
+        final ThreadedRenderer renderer = (ThreadedRenderer) getHardwareRenderer();
+        if (renderer != null) {
+            mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
+                    initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
+
+            // Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
+            // If we want to get the shadow shown while resizing, we would need to elevate a new
+            // element which owns the caption and has the elevation.
+            updateElevation();
+        }
+    }
+
+    @Override
+    public void onWindowDragResizeEnd() {
+        releaseThreadedRenderer();
+    }
+
+    @Override
+    public boolean onContentDrawn(int offsetX, int offsetY, int sizeX, int sizeY) {
+        if (mBackdropFrameRenderer == null) {
+            return false;
+        }
+        return mBackdropFrameRenderer.onContentDrawn(offsetX, offsetY, sizeX, sizeY);
+    }
+
+    @Override
+    public void onRequestDraw(boolean reportNextDraw) {
+        if (mBackdropFrameRenderer != null) {
+            mBackdropFrameRenderer.onRequestDraw(reportNextDraw);
+        } else if (reportNextDraw) {
+            // If render thread is gone, just report immediately.
+            if (isAttachedToWindow()) {
+                getViewRootImpl().reportDrawFinish();
+            }
+        }
+    }
+
+    /** Release the renderer thread which is usually done when the user stops resizing. */
+    private void releaseThreadedRenderer() {
+        if (mBackdropFrameRenderer != null) {
+            mBackdropFrameRenderer.releaseRenderer();
+            mBackdropFrameRenderer = null;
+            // Bring the shadow back.
+            updateElevation();
+        }
+    }
+
+    private void updateElevation() {
+        if (mNonClientDecorView != null) {
+            mNonClientDecorView.updateElevation();
+        }
+    }
+
+    boolean isShowingCaption() {
+        return mNonClientDecorView != null && mNonClientDecorView.isShowingDecor();
+    }
+
+    int getCaptionHeight() {
+        return isShowingCaption() ? mNonClientDecorView.getDecorCaptionHeight() : 0;
+    }
+
     private static class ColorViewState {
         View view = null;
         int targetVisibility = View.INVISIBLE;
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index bee59dc..007ab29 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -19,6 +19,7 @@
 import com.android.internal.R;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Build;
@@ -38,10 +39,29 @@
         mContext = context;
     }
 
+    /**
+     * Returns the maximum number of action buttons that should be permitted within an action
+     * bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit.
+     * "always" items can override this.
+     */
     public int getMaxActionButtons() {
-        return mContext.getResources().getInteger(R.integer.max_action_buttons);
+        final Configuration config = mContext.getResources().getConfiguration();
+        final int width = config.screenWidthDp;
+        final int height = config.screenHeightDp;
+        final int smallest = config.smallestScreenWidthDp;
+        if (smallest > 600 || (width > 960 && height > 720) || (width > 720 && height > 960)) {
+            // For values-w600dp, values-sw600dp and values-xlarge.
+            return 5;
+        } else if (width >= 500 || (width > 640 && height > 480) || (width > 480 && height > 640)) {
+            // For values-w500dp and values-large.
+            return 4;
+        } else if (width >= 360) {
+            // For values-w360dp.
+            return 3;
+        } else {
+            return 2;
+        }
     }
-
     public boolean showsOverflowMenuButton() {
         return true;
     }
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index 89d36ff..81056f2 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -25,7 +25,8 @@
 oneway interface IInputMethodClient {
     void setUsingInputMethod(boolean state);
     void onBindMethod(in InputBindResult res);
-    void onUnbindMethod(int sequence);
+    // unbindReason corresponds to InputMethodClient.UnbindReason.
+    void onUnbindMethod(int sequence, int unbindReason);
     void setActive(boolean active);
     void setUserActionNotificationSequenceNumber(int sequenceNumber);
 }
diff --git a/core/java/com/android/internal/view/InputMethodClient.java b/core/java/com/android/internal/view/InputMethodClient.java
new file mode 100644
index 0000000..a035343
--- /dev/null
+++ b/core/java/com/android/internal/view/InputMethodClient.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.view;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+public final class InputMethodClient {
+    public static final int UNBIND_REASON_UNSPECIFIED = 0;
+    public static final int UNBIND_REASON_SWITCH_CLIENT = 1;
+    public static final int UNBIND_REASON_SWITCH_IME = 2;
+    public static final int UNBIND_REASON_DISCONNECT_IME = 3;
+    public static final int UNBIND_REASON_NO_IME = 4;
+    public static final int UNBIND_REASON_SWITCH_IME_FAILED = 5;
+    public static final int UNBIND_REASON_RESET_IME = 6;
+
+    @Retention(SOURCE)
+    @IntDef({UNBIND_REASON_UNSPECIFIED, UNBIND_REASON_SWITCH_CLIENT, UNBIND_REASON_SWITCH_IME,
+            UNBIND_REASON_DISCONNECT_IME, UNBIND_REASON_NO_IME, UNBIND_REASON_SWITCH_IME_FAILED,
+            UNBIND_REASON_RESET_IME})
+    public @interface UnbindReason {}
+
+    public static String getUnbindReason(@UnbindReason final int reason) {
+        switch (reason) {
+            case UNBIND_REASON_UNSPECIFIED:
+                return "UNSPECIFIED";
+            case UNBIND_REASON_SWITCH_CLIENT:
+                return "SWITCH_CLIENT";
+            case UNBIND_REASON_SWITCH_IME:
+                return "SWITCH_IME";
+            case UNBIND_REASON_DISCONNECT_IME:
+                return "DISCONNECT_IME";
+            case UNBIND_REASON_NO_IME:
+                return "NO_IME";
+            case UNBIND_REASON_SWITCH_IME_FAILED:
+                return "SWITCH_IME_FAILED";
+            case UNBIND_REASON_RESET_IME:
+                return "RESET_IME";
+            default:
+                return "Unknown=" + reason;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/NonClientDecorView.java b/core/java/com/android/internal/widget/NonClientDecorView.java
index 48420da..33b8e05 100644
--- a/core/java/com/android/internal/widget/NonClientDecorView.java
+++ b/core/java/com/android/internal/widget/NonClientDecorView.java
@@ -19,23 +19,19 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 
 import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
-import android.view.ThreadedRenderer;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.view.Window;
-import android.view.WindowCallbacks;
 import android.util.Log;
 import android.util.TypedValue;
 
 import com.android.internal.R;
-import com.android.internal.policy.BackdropFrameRenderer;
+import com.android.internal.policy.DecorView;
 import com.android.internal.policy.PhoneWindow;
 
 /**
@@ -64,7 +60,7 @@
  * This will be mitigated once b/22527834 will be addressed.
  */
 public class NonClientDecorView extends LinearLayout
-        implements View.OnClickListener, View.OnTouchListener, WindowCallbacks {
+        implements View.OnClickListener, View.OnTouchListener {
     private final static String TAG = "NonClientDecorView";
     // The height of a window which has focus in DIP.
     private final int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20;
@@ -72,9 +68,7 @@
     private final int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5;
     private PhoneWindow mOwner = null;
     private boolean mWindowHasShadow = false;
-    public boolean mShowDecor = false;
-    // True when this object is listening for window size changes.
-    private boolean mAttachedCallbacksToRootViewImpl = false;
+    private boolean mShowDecor = false;
 
     // True if the window is being dragged.
     private boolean mDragging = false;
@@ -93,11 +87,6 @@
     // to max until the first layout command has been executed.
     private boolean mAllowUpdateElevation = false;
 
-    private BackdropFrameRenderer mBackdropFrameRenderer = null;
-
-    public Drawable mResizingBackgroundDrawable;
-    public Drawable mCaptionBackgroundDrawable;
-
     public NonClientDecorView(Context context) {
         super(context);
     }
@@ -110,37 +99,10 @@
         super(context, attrs, defStyle);
     }
 
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (!mAttachedCallbacksToRootViewImpl) {
-            // If there is no window callback installed there was no window set before. Set it now.
-            // Note that our ViewRootImpl object will not change.
-            getViewRootImpl().addWindowCallbacks(this);
-            mAttachedCallbacksToRootViewImpl = true;
-        } else if (mBackdropFrameRenderer != null) {
-            // We are resizing and this call happened due to a configuration change. Tell the
-            // renderer about it.
-            mBackdropFrameRenderer.onConfigurationChange();
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mAttachedCallbacksToRootViewImpl) {
-            getViewRootImpl().removeWindowCallbacks(this);
-            mAttachedCallbacksToRootViewImpl = false;
-        }
-    }
-
-    public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow,
-            Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawableDrawable) {
+    public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow) {
         mOwner = owner;
         mWindowHasShadow = windowHasShadow;
         mShowDecor = showDecor;
-        mResizingBackgroundDrawable = resizingBackgroundDrawable;
-        mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
         updateCaptionVisibility();
         if (mWindowHasShadow) {
             initializeElevation();
@@ -290,11 +252,12 @@
      * Note: Windows which have (temporarily) changed their attributes to cover the SystemUI
      *       will get no shadow as they are expected to be "full screen".
      **/
-    private void updateElevation() {
+    public void updateElevation() {
         float elevation = 0;
         // Do not use a shadow when we are in resizing mode (mRenderer not null) since the shadow
         // is bound to the content size and not the target size.
-        if (mWindowHasShadow && mBackdropFrameRenderer == null) {
+        if (mWindowHasShadow
+                && ((DecorView) mOwner.getDecorView()).mBackdropFrameRenderer == null) {
             boolean fill = isFillingScreen();
             elevation = fill ? 0 :
                     (mWindowHasFocus ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP :
@@ -336,77 +299,12 @@
         }
     }
 
-    @Override
-    public void onWindowDragResizeStart(Rect initialBounds) {
-        if (mOwner.isDestroyed()) {
-            // If the owner's window is gone, we should not be able to come here anymore.
-            releaseResources();
-            return;
-        }
-        if (mBackdropFrameRenderer != null) {
-            return;
-        }
-        final ThreadedRenderer renderer =
-                (ThreadedRenderer) mOwner.getDecorView().getHardwareRenderer();
-        if (renderer != null) {
-            mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer, initialBounds);
-            // Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
-            // If we want to get the shadow shown while resizing, we would need to elevate a new
-            // element which owns the caption and has the elevation.
-            updateElevation();
-        }
+    public boolean isShowingDecor() {
+        return mShowDecor;
     }
 
-    @Override
-    public boolean onContentDrawn(int xOffset, int yOffset, int xSize, int ySize) {
-        if (mBackdropFrameRenderer == null) {
-            return false;
-        }
-        return mBackdropFrameRenderer.onContentDrawn(xOffset, yOffset, xSize, ySize);
+    public int getDecorCaptionHeight() {
+        final View caption = getChildAt(0);
+        return (caption != null) ? caption.getHeight() : 0;
     }
-
-    @Override
-    public void onRequestDraw(boolean reportNextDraw) {
-        if (mBackdropFrameRenderer != null) {
-            mBackdropFrameRenderer.onRequestDraw(reportNextDraw);
-        } else if (reportNextDraw) {
-            // If render thread is gone, just report immediately.
-            if (isAttachedToWindow()) {
-                getViewRootImpl().reportDrawFinish();
-            }
-        }
-    }
-
-    @Override
-    public void onWindowDragResizeEnd() {
-        releaseThreadedRenderer();
-    }
-
-    @Override
-    public void onWindowSizeIsChanging(Rect newBounds) {
-        if (mBackdropFrameRenderer != null) {
-            mBackdropFrameRenderer.setTargetRect(newBounds);
-        }
-    }
-
-    /**
-     * Release the renderer thread which is usually done when the user stops resizing.
-     */
-    private void releaseThreadedRenderer() {
-        if (mBackdropFrameRenderer != null) {
-            mBackdropFrameRenderer.releaseRenderer();
-            mBackdropFrameRenderer = null;
-            // Bring the shadow back.
-            updateElevation();
-        }
-    }
-
-    /**
-     * Called when the parent window is destroyed to release all resources. Note that this will also
-     * destroy the renderer thread.
-     */
-    private void releaseResources() {
-        releaseThreadedRenderer();
-    }
-
 }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 815d330..65e8058 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -608,15 +608,6 @@
       kEMIntFast,
       kEMJitCompiler,
     } executionMode = kEMDefault;
-    char profilePeriod[sizeof("-Xprofile-period:")-1 + PROPERTY_VALUE_MAX];
-    char profileDuration[sizeof("-Xprofile-duration:")-1 + PROPERTY_VALUE_MAX];
-    char profileInterval[sizeof("-Xprofile-interval:")-1 + PROPERTY_VALUE_MAX];
-    char profileBackoff[sizeof("-Xprofile-backoff:")-1 + PROPERTY_VALUE_MAX];
-    char profileTopKThreshold[sizeof("-Xprofile-top-k-threshold:")-1 + PROPERTY_VALUE_MAX];
-    char profileTopKChangeThreshold[sizeof("-Xprofile-top-k-change-threshold:")-1 +
-                                    PROPERTY_VALUE_MAX];
-    char profileType[sizeof("-Xprofile-type:")-1 + PROPERTY_VALUE_MAX];
-    char profileMaxStackDepth[sizeof("-Xprofile-max-stack-depth:")-1 + PROPERTY_VALUE_MAX];
     char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];
     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
     char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
@@ -835,60 +826,6 @@
         addOption(localeOption);
     }
 
-    /*
-     * Set profiler options
-     */
-    // Whether or not the profiler should be enabled.
-    property_get("dalvik.vm.profiler", propBuf, "0");
-    if (propBuf[0] == '1') {
-        addOption("-Xenable-profiler");
-    }
-
-    // Whether the profile should start upon app startup or be delayed by some random offset
-    // (in seconds) that is bound between 0 and a fixed value.
-    property_get("dalvik.vm.profile.start-immed", propBuf, "0");
-    if (propBuf[0] == '1') {
-        addOption("-Xprofile-start-immediately");
-    }
-
-    // Number of seconds during profile runs.
-    parseRuntimeOption("dalvik.vm.profile.period-secs", profilePeriod, "-Xprofile-period:");
-
-    // Length of each profile run (seconds).
-    parseRuntimeOption("dalvik.vm.profile.duration-secs",
-                       profileDuration,
-                       "-Xprofile-duration:");
-
-    // Polling interval during profile run (microseconds).
-    parseRuntimeOption("dalvik.vm.profile.interval-us", profileInterval, "-Xprofile-interval:");
-
-    // Coefficient for period backoff.  The the period is multiplied
-    // by this value after each profile run.
-    parseRuntimeOption("dalvik.vm.profile.backoff-coeff", profileBackoff, "-Xprofile-backoff:");
-
-    // Top K% of samples that are considered relevant when
-    // deciding if the app should be recompiled.
-    parseRuntimeOption("dalvik.vm.profile.top-k-thr",
-                       profileTopKThreshold,
-                       "-Xprofile-top-k-threshold:");
-
-    // The threshold after which a change in the structure of the
-    // top K% profiled samples becomes significant and triggers
-    // recompilation. A change in profile is considered
-    // significant if X% (top-k-change-threshold) of the top K%
-    // (top-k-threshold property) samples has changed.
-    parseRuntimeOption("dalvik.vm.profile.top-k-ch-thr",
-                       profileTopKChangeThreshold,
-                       "-Xprofile-top-k-change-threshold:");
-
-    // Type of profile data.
-    parseRuntimeOption("dalvik.vm.profiler.type", profileType, "-Xprofile-type:");
-
-    // Depth of bounded stack data
-    parseRuntimeOption("dalvik.vm.profile.stack-depth",
-                       profileMaxStackDepth,
-                       "-Xprofile-max-stack-depth:");
-
     // Trace files are stored in /data/misc/trace which is writable only in debug mode.
     property_get("ro.debuggable", propBuf, "0");
     if (strcmp(propBuf, "1") == 0) {
diff --git a/core/jni/android_view_PointerIcon.cpp b/core/jni/android_view_PointerIcon.cpp
index d04adbf..d7e2c02 100644
--- a/core/jni/android_view_PointerIcon.cpp
+++ b/core/jni/android_view_PointerIcon.cpp
@@ -24,6 +24,7 @@
 #include <android_runtime/Log.h>
 #include <utils/Log.h>
 #include <android/graphics/GraphicsJNI.h>
+#include "ScopedLocalRef.h"
 
 #include "core_jni_helpers.h"
 
@@ -35,6 +36,8 @@
     jfieldID mBitmap;
     jfieldID mHotSpotX;
     jfieldID mHotSpotY;
+    jfieldID mBitmapFrames;
+    jfieldID mDurationPerFrame;
     jmethodID getSystemIcon;
     jmethodID load;
 } gPointerIconClassInfo;
@@ -84,6 +87,19 @@
         env->DeleteLocalRef(bitmapObj);
     }
 
+    ScopedLocalRef<jobjectArray> bitmapFramesObj(env, reinterpret_cast<jobjectArray>(
+            env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmapFrames)));
+    if (bitmapFramesObj.get()) {
+        outPointerIcon->durationPerFrame = env->GetIntField(
+                loadedPointerIconObj, gPointerIconClassInfo.mDurationPerFrame);
+        jsize size = env->GetArrayLength(bitmapFramesObj.get());
+        outPointerIcon->bitmapFrames.resize(size);
+        for (jsize i = 0; i < size; ++i) {
+            ScopedLocalRef<jobject> bitmapObj(env, env->GetObjectArrayElement(bitmapFramesObj.get(), i));
+            GraphicsJNI::getSkBitmap(env, bitmapObj.get(), &(outPointerIcon->bitmapFrames[i]));
+        }
+    }
+
     env->DeleteLocalRef(loadedPointerIconObj);
     return OK;
 }
@@ -121,6 +137,12 @@
     gPointerIconClassInfo.mHotSpotY = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
             "mHotSpotY", "F");
 
+    gPointerIconClassInfo.mBitmapFrames = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
+            "mBitmapFrames", "[Landroid/graphics/Bitmap;");
+
+    gPointerIconClassInfo.mDurationPerFrame = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
+            "mDurationPerFrame", "I");
+
     gPointerIconClassInfo.getSystemIcon = GetStaticMethodIDOrDie(env, gPointerIconClassInfo.clazz,
             "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;");
 
diff --git a/core/jni/android_view_PointerIcon.h b/core/jni/android_view_PointerIcon.h
index 86f288d..ca08085 100644
--- a/core/jni/android_view_PointerIcon.h
+++ b/core/jni/android_view_PointerIcon.h
@@ -19,6 +19,8 @@
 
 #include "jni.h"
 
+#include <vector>
+
 #include <utils/Errors.h>
 #include <SkBitmap.h>
 
@@ -69,6 +71,8 @@
     SkBitmap bitmap;
     float hotSpotX;
     float hotSpotY;
+    std::vector<SkBitmap> bitmapFrames;
+    int32_t durationPerFrame;
 
     inline bool isNullIcon() {
         return style == POINTER_ICON_STYLE_NULL;
@@ -79,6 +83,8 @@
         bitmap.reset();
         hotSpotX = 0;
         hotSpotY = 0;
+        bitmapFrames.clear();
+        durationPerFrame = 0;
     }
 };
 
diff --git a/core/res/res/drawable-mdpi/pointer_wait_0.png b/core/res/res/drawable-mdpi/pointer_wait_0.png
new file mode 100644
index 0000000..adb7806
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_1.png b/core/res/res/drawable-mdpi/pointer_wait_1.png
new file mode 100644
index 0000000..fc6b42f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_10.png b/core/res/res/drawable-mdpi/pointer_wait_10.png
new file mode 100644
index 0000000..02968b5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_10.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_11.png b/core/res/res/drawable-mdpi/pointer_wait_11.png
new file mode 100644
index 0000000..24f866b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_11.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_12.png b/core/res/res/drawable-mdpi/pointer_wait_12.png
new file mode 100644
index 0000000..d1a31bc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_12.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_13.png b/core/res/res/drawable-mdpi/pointer_wait_13.png
new file mode 100644
index 0000000..b0c6798
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_13.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_14.png b/core/res/res/drawable-mdpi/pointer_wait_14.png
new file mode 100644
index 0000000..721e86d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_14.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_15.png b/core/res/res/drawable-mdpi/pointer_wait_15.png
new file mode 100644
index 0000000..adb0199
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_15.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_16.png b/core/res/res/drawable-mdpi/pointer_wait_16.png
new file mode 100644
index 0000000..3695c18
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_16.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_17.png b/core/res/res/drawable-mdpi/pointer_wait_17.png
new file mode 100644
index 0000000..861605e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_17.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_18.png b/core/res/res/drawable-mdpi/pointer_wait_18.png
new file mode 100644
index 0000000..f5dfdcf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_18.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_19.png b/core/res/res/drawable-mdpi/pointer_wait_19.png
new file mode 100644
index 0000000..9d51f79
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_19.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_2.png b/core/res/res/drawable-mdpi/pointer_wait_2.png
new file mode 100644
index 0000000..d73a154
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_20.png b/core/res/res/drawable-mdpi/pointer_wait_20.png
new file mode 100644
index 0000000..81d1d51
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_20.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_21.png b/core/res/res/drawable-mdpi/pointer_wait_21.png
new file mode 100644
index 0000000..331820b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_21.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_22.png b/core/res/res/drawable-mdpi/pointer_wait_22.png
new file mode 100644
index 0000000..2678d32
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_22.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_23.png b/core/res/res/drawable-mdpi/pointer_wait_23.png
new file mode 100644
index 0000000..d54d9eb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_23.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_24.png b/core/res/res/drawable-mdpi/pointer_wait_24.png
new file mode 100644
index 0000000..442ace7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_24.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_25.png b/core/res/res/drawable-mdpi/pointer_wait_25.png
new file mode 100644
index 0000000..27ce60d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_25.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_26.png b/core/res/res/drawable-mdpi/pointer_wait_26.png
new file mode 100644
index 0000000..8143634
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_26.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_27.png b/core/res/res/drawable-mdpi/pointer_wait_27.png
new file mode 100644
index 0000000..496ab9a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_27.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_28.png b/core/res/res/drawable-mdpi/pointer_wait_28.png
new file mode 100644
index 0000000..a2aab2b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_28.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_29.png b/core/res/res/drawable-mdpi/pointer_wait_29.png
new file mode 100644
index 0000000..646d153
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_29.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_3.png b/core/res/res/drawable-mdpi/pointer_wait_3.png
new file mode 100644
index 0000000..9f45afe
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_30.png b/core/res/res/drawable-mdpi/pointer_wait_30.png
new file mode 100644
index 0000000..27b3fc4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_30.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_31.png b/core/res/res/drawable-mdpi/pointer_wait_31.png
new file mode 100644
index 0000000..6dbe184
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_31.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_32.png b/core/res/res/drawable-mdpi/pointer_wait_32.png
new file mode 100644
index 0000000..9f072ef
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_32.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_33.png b/core/res/res/drawable-mdpi/pointer_wait_33.png
new file mode 100644
index 0000000..881ec5f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_33.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_34.png b/core/res/res/drawable-mdpi/pointer_wait_34.png
new file mode 100644
index 0000000..94961e3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_34.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_35.png b/core/res/res/drawable-mdpi/pointer_wait_35.png
new file mode 100644
index 0000000..dfa65d7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_35.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_4.png b/core/res/res/drawable-mdpi/pointer_wait_4.png
new file mode 100644
index 0000000..5d3d652
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_5.png b/core/res/res/drawable-mdpi/pointer_wait_5.png
new file mode 100644
index 0000000..d440a82
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_6.png b/core/res/res/drawable-mdpi/pointer_wait_6.png
new file mode 100644
index 0000000..ae65590
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_6.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_7.png b/core/res/res/drawable-mdpi/pointer_wait_7.png
new file mode 100644
index 0000000..cd84aa5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_7.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_8.png b/core/res/res/drawable-mdpi/pointer_wait_8.png
new file mode 100644
index 0000000..0b81a9a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_8.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_wait_9.png b/core/res/res/drawable-mdpi/pointer_wait_9.png
new file mode 100644
index 0000000..c13a90c1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/pointer_wait_9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_0.png b/core/res/res/drawable-xhdpi/pointer_wait_0.png
new file mode 100644
index 0000000..5396784
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_0.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_1.png b/core/res/res/drawable-xhdpi/pointer_wait_1.png
new file mode 100644
index 0000000..25edbf5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_1.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_10.png b/core/res/res/drawable-xhdpi/pointer_wait_10.png
new file mode 100644
index 0000000..96d93a9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_10.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_11.png b/core/res/res/drawable-xhdpi/pointer_wait_11.png
new file mode 100644
index 0000000..cd78675
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_11.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_12.png b/core/res/res/drawable-xhdpi/pointer_wait_12.png
new file mode 100644
index 0000000..1b2c7b2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_12.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_13.png b/core/res/res/drawable-xhdpi/pointer_wait_13.png
new file mode 100644
index 0000000..3b00f10
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_13.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_14.png b/core/res/res/drawable-xhdpi/pointer_wait_14.png
new file mode 100644
index 0000000..eca5c3f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_14.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_15.png b/core/res/res/drawable-xhdpi/pointer_wait_15.png
new file mode 100644
index 0000000..0fc2085
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_15.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_16.png b/core/res/res/drawable-xhdpi/pointer_wait_16.png
new file mode 100644
index 0000000..db13cf6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_16.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_17.png b/core/res/res/drawable-xhdpi/pointer_wait_17.png
new file mode 100644
index 0000000..9b6fac5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_17.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_18.png b/core/res/res/drawable-xhdpi/pointer_wait_18.png
new file mode 100644
index 0000000..c56ff6c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_18.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_19.png b/core/res/res/drawable-xhdpi/pointer_wait_19.png
new file mode 100644
index 0000000..22b7c90
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_19.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_2.png b/core/res/res/drawable-xhdpi/pointer_wait_2.png
new file mode 100644
index 0000000..4bdbe3f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_2.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_20.png b/core/res/res/drawable-xhdpi/pointer_wait_20.png
new file mode 100644
index 0000000..6d042fb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_20.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_21.png b/core/res/res/drawable-xhdpi/pointer_wait_21.png
new file mode 100644
index 0000000..e3ab63f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_21.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_22.png b/core/res/res/drawable-xhdpi/pointer_wait_22.png
new file mode 100644
index 0000000..b25f6b7d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_22.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_23.png b/core/res/res/drawable-xhdpi/pointer_wait_23.png
new file mode 100644
index 0000000..49faba9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_23.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_24.png b/core/res/res/drawable-xhdpi/pointer_wait_24.png
new file mode 100644
index 0000000..e91c340
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_24.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_25.png b/core/res/res/drawable-xhdpi/pointer_wait_25.png
new file mode 100644
index 0000000..f4785c6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_25.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_26.png b/core/res/res/drawable-xhdpi/pointer_wait_26.png
new file mode 100644
index 0000000..ea902f8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_26.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_27.png b/core/res/res/drawable-xhdpi/pointer_wait_27.png
new file mode 100644
index 0000000..7d628c3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_27.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_28.png b/core/res/res/drawable-xhdpi/pointer_wait_28.png
new file mode 100644
index 0000000..92d6dc1
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_28.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_29.png b/core/res/res/drawable-xhdpi/pointer_wait_29.png
new file mode 100644
index 0000000..5a8d18915
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_29.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_3.png b/core/res/res/drawable-xhdpi/pointer_wait_3.png
new file mode 100644
index 0000000..de4d79c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_3.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_30.png b/core/res/res/drawable-xhdpi/pointer_wait_30.png
new file mode 100644
index 0000000..ba04b5e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_30.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_31.png b/core/res/res/drawable-xhdpi/pointer_wait_31.png
new file mode 100644
index 0000000..3ef8e98
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_31.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_32.png b/core/res/res/drawable-xhdpi/pointer_wait_32.png
new file mode 100644
index 0000000..3297a7d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_32.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_33.png b/core/res/res/drawable-xhdpi/pointer_wait_33.png
new file mode 100644
index 0000000..b0ac3b9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_33.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_34.png b/core/res/res/drawable-xhdpi/pointer_wait_34.png
new file mode 100644
index 0000000..0eaa386
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_34.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_35.png b/core/res/res/drawable-xhdpi/pointer_wait_35.png
new file mode 100644
index 0000000..73894d8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_35.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_4.png b/core/res/res/drawable-xhdpi/pointer_wait_4.png
new file mode 100644
index 0000000..ea44e85
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_4.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_5.png b/core/res/res/drawable-xhdpi/pointer_wait_5.png
new file mode 100644
index 0000000..46c399d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_5.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_6.png b/core/res/res/drawable-xhdpi/pointer_wait_6.png
new file mode 100644
index 0000000..3b9aff6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_6.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_7.png b/core/res/res/drawable-xhdpi/pointer_wait_7.png
new file mode 100644
index 0000000..a54edc0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_7.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_8.png b/core/res/res/drawable-xhdpi/pointer_wait_8.png
new file mode 100644
index 0000000..2f30732
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_8.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_wait_9.png b/core/res/res/drawable-xhdpi/pointer_wait_9.png
new file mode 100644
index 0000000..f39c7a7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_wait_9.png
Binary files differ
diff --git a/core/res/res/drawable/pointer_wait.xml b/core/res/res/drawable/pointer_wait.xml
new file mode 100644
index 0000000..8955ce8
--- /dev/null
+++ b/core/res/res/drawable/pointer_wait.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
+  <item android:drawable="@drawable/pointer_wait_1" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_2" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_3" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_4" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_5" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_6" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_7" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_8" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_9" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_10" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_11" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_12" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_13" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_14" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_15" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_16" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_17" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_18" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_19" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_20" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_21" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_22" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_23" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_24" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_25" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_26" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_27" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_28" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_29" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_30" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_31" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_32" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_33" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_34" android:duration="25"/>
+  <item android:drawable="@drawable/pointer_wait_35" android:duration="25"/>
+</animation-list>
diff --git a/core/res/res/drawable/pointer_wait_icon.xml b/core/res/res/drawable/pointer_wait_icon.xml
new file mode 100644
index 0000000..d9b03b0
--- /dev/null
+++ b/core/res/res/drawable/pointer_wait_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/pointer_wait"
+    android:hotSpotX="7dp"
+    android:hotSpotY="7dp" />
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 94e9c4e..9c45c12 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -22,10 +22,6 @@
     <dimen name="thumbnail_width">360dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_height">360dp</dimen>
-    <!-- The maximum number of action buttons that should be permitted within
-         an action bar/action mode. This will be used to determine how many
-         showAsAction="ifRoom" items can fit. "always" items can override this. -->
-    <integer name="max_action_buttons">5</integer>
     <!-- Default height of an action bar. -->
     <dimen name="action_bar_default_height">56dip</dimen>
     <!-- Vertical padding around action bar icons. -->
@@ -88,7 +84,7 @@
     <!-- Size of the generic status lines keyguard's status view  -->
     <dimen name="kg_status_line_font_size">16sp</dimen>
 
-    <!-- Top margin for the clock view --> 
+    <!-- Top margin for the clock view -->
     <dimen name="kg_clock_top_margin">0dp</dimen>
 
     <!-- Size of margin on the right of keyguard's status view -->
diff --git a/core/res/res/values-w360dp/dimens.xml b/core/res/res/values-w360dp/dimens.xml
deleted file mode 100644
index 0f5d656..0000000
--- a/core/res/res/values-w360dp/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- The maximum number of action buttons that should be permitted within
-         an action bar/action mode. This will be used to determine how many
-         showAsAction="ifRoom" items can fit. "always" items can override this. -->
-    <integer name="max_action_buttons">3</integer>
-</resources>
diff --git a/core/res/res/values-w500dp/dimens.xml b/core/res/res/values-w500dp/dimens.xml
deleted file mode 100644
index 68841ca..0000000
--- a/core/res/res/values-w500dp/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- The maximum number of action buttons that should be permitted within
-         an action bar/action mode. This will be used to determine how many
-         showAsAction="ifRoom" items can fit. "always" items can override this. -->
-    <integer name="max_action_buttons">4</integer>
-</resources>
diff --git a/core/res/res/values-w600dp/dimens.xml b/core/res/res/values-w600dp/dimens.xml
deleted file mode 100644
index 83c45b5..0000000
--- a/core/res/res/values-w600dp/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- The maximum number of action buttons that should be permitted within
-         an action bar/action mode. This will be used to determine how many
-         showAsAction="ifRoom" items can fit. "always" items can override this. -->
-    <integer name="max_action_buttons">5</integer>
-</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 90fc22b..04f4fc2 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4248,7 +4248,8 @@
         <attr name="autoLink" />
         <!-- If set to false, keeps the movement method from being set
              to the link movement method even if autoLink causes links
-             to be found. -->
+             to be found or the input text contains a
+             {@link android.text.style.ClickableSpan ClickableSpan}. -->
         <attr name="linksClickable" format="boolean" />
         <!-- If set, specifies that this TextView has a numeric input method.
              The default is false.
@@ -7631,6 +7632,8 @@
         <attr name="pointerIconHand" format="reference"/>
         <!-- Reference to a pointer drawable with STYLE_HELP -->
         <attr name="pointerIconHelp" format="reference"/>
+        <!-- Reference to a pointer drawable with STYLE_WAIT -->
+        <attr name="pointerIconWait" format="reference"/>
         <!-- Reference to a pointer drawable with STYLE_CELL -->
         <attr name="pointerIconCell" format="reference"/>
         <!-- Reference to a pointer drawable with STYLE_CROSSHAIR -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 28756f5..01daf26 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -25,10 +25,7 @@
     <!-- The standard size (both width and height) of an application icon that
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>
-    <!-- The maximum number of action buttons that should be permitted within
-         an action bar/action mode. This will be used to determine how many
-         showAsAction="ifRoom" items can fit. "always" items can override this. -->
-    <integer name="max_action_buttons">2</integer>
+
     <dimen name="toast_y_offset">64dip</dimen>
     <!-- Height of the status bar -->
     <dimen name="status_bar_height">24dp</dimen>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index b831df8..eb99077 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1339,6 +1339,7 @@
         <item name="pointerIconHand">@drawable/pointer_hand_icon</item>
         <item name="pointerIconContextMenu">@drawable/pointer_context_menu_icon</item>
         <item name="pointerIconHelp">@drawable/pointer_help_icon</item>
+        <item name="pointerIconWait">@drawable/pointer_wait_icon</item>
         <item name="pointerIconCell">@drawable/pointer_cell_icon</item>
         <item name="pointerIconCrosshair">@drawable/pointer_crosshair_icon</item>
         <item name="pointerIconText">@drawable/pointer_text_icon</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e8f6b46..556467a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -401,7 +401,6 @@
   <java-symbol type="integer" name="db_connection_pool_size" />
   <java-symbol type="integer" name="db_journal_size_limit" />
   <java-symbol type="integer" name="db_wal_autocheckpoint" />
-  <java-symbol type="integer" name="max_action_buttons" />
   <java-symbol type="integer" name="config_soundEffectVolumeDb" />
   <java-symbol type="integer" name="config_lockSoundVolumeDb" />
   <java-symbol type="integer" name="config_multiuserMaximumUsers" />
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index c31a8b7..8c20ddc 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -101,20 +101,21 @@
      */
     public static void install() {
         Provider[] providers = Security.getProviders();
-        int bcProviderPosition = -1;
-        for (int position = 0; position < providers.length; position++) {
-            Provider provider = providers[position];
+        int bcProviderIndex = -1;
+        for (int i = 0; i < providers.length; i++) {
+            Provider provider = providers[i];
             if ("BC".equals(provider.getName())) {
-                bcProviderPosition = position;
+                bcProviderIndex = i;
                 break;
             }
         }
 
         Security.addProvider(new AndroidKeyStoreProvider());
         Provider workaroundProvider = new AndroidKeyStoreBCWorkaroundProvider();
-        if (bcProviderPosition != -1) {
+        if (bcProviderIndex != -1) {
             // Bouncy Castle provider found -- install the workaround provider above it.
-            Security.insertProviderAt(workaroundProvider, bcProviderPosition);
+            // insertProviderAt uses 1-based positions.
+            Security.insertProviderAt(workaroundProvider, bcProviderIndex + 1);
         } else {
             // Bouncy Castle provider not found -- install the workaround provider at lowest
             // priority.
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 39b7ecb..4cfbb2a 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -18,6 +18,7 @@
 #include "Extensions.h"
 
 #include <GLES2/gl2.h>
+#include <log/log.h>
 
 #include <thread>
 #include <mutex>
@@ -29,6 +30,7 @@
 static std::once_flag sInitializedFlag;
 
 const DeviceInfo* DeviceInfo::get() {
+    LOG_ALWAYS_FATAL_IF(!sDeviceInfo, "DeviceInfo not yet initialized.");
     return sDeviceInfo;
 }
 
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index b04f16f..96cac7e 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -21,10 +21,10 @@
 #include "renderstate/OffscreenBufferPool.h"
 #include "utils/FatVector.h"
 #include "utils/PaintUtils.h"
+#include "utils/TraceUtils.h"
 
 #include <SkCanvas.h>
 #include <SkPathOps.h>
-#include <utils/Trace.h>
 #include <utils/TypeHelpers.h>
 
 namespace android {
@@ -331,13 +331,15 @@
         RenderNode* layerNode = layers.entries()[i].renderNode;
         const Rect& layerDamage = layers.entries()[i].damage;
 
-        saveForLayer(layerNode->getWidth(), layerNode->getHeight(),
-                layerDamage, nullptr, layerNode);
-        mCanvasState.writableSnapshot()->setClip(
-                layerDamage.left, layerDamage.top, layerDamage.right, layerDamage.bottom);
+        // map current light center into RenderNode's coordinate space
+        Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter();
+        layerNode->getLayer()->inverseTransformInWindow.mapPoint3d(lightCenter);
+
+        saveForLayer(layerNode->getWidth(), layerNode->getHeight(), 0, 0,
+                layerDamage, lightCenter, nullptr, layerNode);
 
         if (layerNode->getDisplayList()) {
-            deferImpl(*(layerNode->getDisplayList()));
+            deferDisplayList(*(layerNode->getDisplayList()));
         }
         restoreForLayer();
     }
@@ -363,7 +365,7 @@
     mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
             0, 0, viewportWidth, viewportHeight, lightCenter);
 
-    deferImpl(displayList);
+    deferDisplayList(displayList);
 }
 
 void OpReorderer::onViewportInitialized() {}
@@ -371,18 +373,99 @@
 void OpReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
 
 void OpReorderer::deferNodePropsAndOps(RenderNode& node) {
-    if (node.applyViewProperties(mCanvasState, mAllocator)) {
-        // not rejected so render
+    const RenderProperties& properties = node.properties();
+    const Outline& outline = properties.getOutline();
+    if (properties.getAlpha() <= 0
+            || (outline.getShouldClip() && outline.isEmpty())
+            || properties.getScaleX() == 0
+            || properties.getScaleY() == 0) {
+        return; // rejected
+    }
+
+    if (properties.getLeft() != 0 || properties.getTop() != 0) {
+        mCanvasState.translate(properties.getLeft(), properties.getTop());
+    }
+    if (properties.getStaticMatrix()) {
+        mCanvasState.concatMatrix(*properties.getStaticMatrix());
+    } else if (properties.getAnimationMatrix()) {
+        mCanvasState.concatMatrix(*properties.getAnimationMatrix());
+    }
+    if (properties.hasTransformMatrix()) {
+        if (properties.isTransformTranslateOnly()) {
+            mCanvasState.translate(properties.getTranslationX(), properties.getTranslationY());
+        } else {
+            mCanvasState.concatMatrix(*properties.getTransformMatrix());
+        }
+    }
+
+    const int width = properties.getWidth();
+    const int height = properties.getHeight();
+
+    Rect saveLayerBounds; // will be set to non-empty if saveLayer needed
+    const bool isLayer = properties.effectiveLayerType() != LayerType::None;
+    int clipFlags = properties.getClippingFlags();
+    if (properties.getAlpha() < 1) {
+        if (isLayer) {
+            clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
+        }
+        if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering())) {
+            // simply scale rendering content's alpha
+            mCanvasState.scaleAlpha(properties.getAlpha());
+        } else {
+            // schedule saveLayer by initializing saveLayerBounds
+            saveLayerBounds.set(0, 0, width, height);
+            if (clipFlags) {
+                properties.getClippingRectForFlags(clipFlags, &saveLayerBounds);
+                clipFlags = 0; // all clipping done by savelayer
+            }
+        }
+
+        if (CC_UNLIKELY(ATRACE_ENABLED() && properties.promotedToLayer())) {
+            // pretend alpha always causes savelayer to warn about
+            // performance problem affecting old versions
+            ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", node.getName(), width, height);
+        }
+    }
+    if (clipFlags) {
+        Rect clipRect;
+        properties.getClippingRectForFlags(clipFlags, &clipRect);
+        mCanvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
+                SkRegion::kIntersect_Op);
+    }
+
+    if (properties.getRevealClip().willClip()) {
+        Rect bounds;
+        properties.getRevealClip().getBounds(&bounds);
+        mCanvasState.setClippingRoundRect(mAllocator,
+                bounds, properties.getRevealClip().getRadius());
+    } else if (properties.getOutline().willClip()) {
+        mCanvasState.setClippingOutline(mAllocator, &(properties.getOutline()));
+    }
+
+    if (!mCanvasState.quickRejectConservative(0, 0, width, height)) {
+        // not rejected, so defer render as either Layer, or direct (possibly wrapped in saveLayer)
         if (node.getLayer()) {
             // HW layer
             LayerOp* drawLayerOp = new (mAllocator) LayerOp(node);
             BakedOpState* bakedOpState = tryBakeOpState(*drawLayerOp);
             if (bakedOpState) {
-                // Layer will be drawn into parent layer (which is now current, since we popped mLayerStack)
+                // Node's layer already deferred, schedule it to render into parent layer
                 currentLayer().deferUnmergeableOp(mAllocator, bakedOpState, OpBatchType::Bitmap);
             }
+        } else if (CC_UNLIKELY(!saveLayerBounds.isEmpty())) {
+            // draw DisplayList contents within temporary, since persisted layer could not be used.
+            // (temp layers are clipped to viewport, since they don't persist offscreen content)
+            SkPaint saveLayerPaint;
+            saveLayerPaint.setAlpha(properties.getAlpha());
+            onBeginLayerOp(*new (mAllocator) BeginLayerOp(
+                    saveLayerBounds,
+                    Matrix4::identity(),
+                    saveLayerBounds,
+                    &saveLayerPaint));
+            deferDisplayList(*(node.getDisplayList()));
+            onEndLayerOp(*new (mAllocator) EndLayerOp());
         } else {
-            deferImpl(*(node.getDisplayList()));
+            deferDisplayList(*(node.getDisplayList()));
         }
     }
 }
@@ -535,7 +618,7 @@
  */
 #define OP_RECEIVER(Type) \
         [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); },
-void OpReorderer::deferImpl(const DisplayList& displayList) {
+void OpReorderer::deferDisplayList(const DisplayList& displayList) {
     static std::function<void(OpReorderer& reorderer, const RecordedOp&)> receivers[] = {
         MAP_OPS(OP_RECEIVER)
     };
@@ -600,34 +683,21 @@
     currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices);
 }
 
-void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const Rect& repaintRect,
+void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
+        float contentTranslateX, float contentTranslateY,
+        const Rect& repaintRect,
+        const Vector3& lightCenter,
         const BeginLayerOp* beginLayerOp, RenderNode* renderNode) {
-
-    auto previous = mCanvasState.currentSnapshot();
     mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
-    mCanvasState.writableSnapshot()->transform->loadIdentity();
     mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight);
     mCanvasState.writableSnapshot()->roundRectClipState = nullptr;
-
-    Vector3 lightCenter = previous->getRelativeLightCenter();
-    if (renderNode) {
-        Matrix4& inverse = renderNode->getLayer()->inverseTransformInWindow;
-        inverse.mapPoint3d(lightCenter);
-    } else {
-        // Combine all transforms used to present saveLayer content:
-        // parent content transform * canvas transform * bounds offset
-        Matrix4 contentTransform(*previous->transform);
-        contentTransform.multiply(beginLayerOp->localMatrix);
-        contentTransform.translate(beginLayerOp->unmappedBounds.left, beginLayerOp->unmappedBounds.top);
-
-        // inverse the total transform, to map light center into layer-relative space
-        Matrix4 inverse;
-        inverse.loadInverse(contentTransform);
-        inverse.mapPoint3d(lightCenter);
-    }
     mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter);
+    mCanvasState.writableSnapshot()->transform->loadTranslate(
+            contentTranslateX, contentTranslateY, 0);
+    mCanvasState.writableSnapshot()->setClip(
+            repaintRect.left, repaintRect.top, repaintRect.right, repaintRect.bottom);
 
-    // create a new layer, and push its index on the stack
+    // create a new layer repaint, and push its index on the stack
     mLayerStack.push_back(mLayerReorderers.size());
     mLayerReorderers.emplace_back(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode);
 }
@@ -640,9 +710,48 @@
 
 // TODO: test rejection at defer time, where the bounds become empty
 void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) {
-    const uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth();
-    const uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight();
-    saveForLayer(layerWidth, layerHeight, Rect(layerWidth, layerHeight), &op, nullptr);
+    uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth();
+    uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight();
+
+    auto previous = mCanvasState.currentSnapshot();
+    Vector3 lightCenter = previous->getRelativeLightCenter();
+
+    // Combine all transforms used to present saveLayer content:
+    // parent content transform * canvas transform * bounds offset
+    Matrix4 contentTransform(*previous->transform);
+    contentTransform.multiply(op.localMatrix);
+    contentTransform.translate(op.unmappedBounds.left, op.unmappedBounds.top);
+
+    Matrix4 inverseContentTransform;
+    inverseContentTransform.loadInverse(contentTransform);
+
+    // map the light center into layer-relative space
+    inverseContentTransform.mapPoint3d(lightCenter);
+
+    // Clip bounds of temporary layer to parent's clip rect, so:
+    Rect saveLayerBounds(layerWidth, layerHeight);
+    //     1) transform Rect(width, height) into parent's space
+    //        note: left/top offsets put in contentTransform above
+    contentTransform.mapRect(saveLayerBounds);
+    //     2) intersect with parent's clip
+    saveLayerBounds.doIntersect(previous->getRenderTargetClip());
+    //     3) and transform back
+    inverseContentTransform.mapRect(saveLayerBounds);
+    saveLayerBounds.doIntersect(Rect(layerWidth, layerHeight));
+    saveLayerBounds.roundOut();
+
+    // if bounds are reduced, will clip the layer's area by reducing required bounds...
+    layerWidth = saveLayerBounds.getWidth();
+    layerHeight = saveLayerBounds.getHeight();
+    // ...and shifting drawing content to account for left/top side clipping
+    float contentTranslateX = -saveLayerBounds.left;
+    float contentTranslateY = -saveLayerBounds.top;
+
+    saveForLayer(layerWidth, layerHeight,
+            contentTranslateX, contentTranslateY,
+            Rect(layerWidth, layerHeight),
+            lightCenter,
+            &op, nullptr);
 }
 
 void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) {
diff --git a/libs/hwui/OpReorderer.h b/libs/hwui/OpReorderer.h
index 09d5cbc..976f413 100644
--- a/libs/hwui/OpReorderer.h
+++ b/libs/hwui/OpReorderer.h
@@ -190,7 +190,10 @@
         Positive
     };
     void saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
-            const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
+            float contentTranslateX, float contentTranslateY,
+            const Rect& repaintRect,
+            const Vector3& lightCenter,
+            const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
     void restoreForLayer();
 
     LayerReorderer& currentLayer() { return mLayerReorderers[mLayerStack.back()]; }
@@ -204,7 +207,7 @@
 
     void deferShadow(const RenderNodeOp& casterOp);
 
-    void deferImpl(const DisplayList& displayList);
+    void deferDisplayList(const DisplayList& displayList);
 
     template <typename V>
     void defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes);
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 50199db..0736a10 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -276,7 +276,7 @@
     }
 
     void dump(const char* label = nullptr) const {
-        ALOGD("%s[l=%f t=%f r=%f b=%f]", label ? label : "Rect", left, top, right, bottom);
+        ALOGD("%s[l=%.2f t=%.2f r=%.2f b=%.2f]", label ? label : "Rect", left, top, right, bottom);
     }
 }; // class Rect
 
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 2713f46..716d536 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -524,76 +524,6 @@
     }
 }
 
-bool RenderNode::applyViewProperties(CanvasState& canvasState, LinearAllocator& allocator) const {
-    const Outline& outline = properties().getOutline();
-    if (properties().getAlpha() <= 0
-            || (outline.getShouldClip() && outline.isEmpty())
-            || properties().getScaleX() == 0
-            || properties().getScaleY() == 0) {
-        return false; // rejected
-    }
-
-    if (properties().getLeft() != 0 || properties().getTop() != 0) {
-        canvasState.translate(properties().getLeft(), properties().getTop());
-    }
-    if (properties().getStaticMatrix()) {
-        canvasState.concatMatrix(*properties().getStaticMatrix());
-    } else if (properties().getAnimationMatrix()) {
-        canvasState.concatMatrix(*properties().getAnimationMatrix());
-    }
-    if (properties().hasTransformMatrix()) {
-        if (properties().isTransformTranslateOnly()) {
-            canvasState.translate(properties().getTranslationX(), properties().getTranslationY());
-        } else {
-            canvasState.concatMatrix(*properties().getTransformMatrix());
-        }
-    }
-
-    const bool isLayer = properties().effectiveLayerType() != LayerType::None;
-    int clipFlags = properties().getClippingFlags();
-    if (properties().getAlpha() < 1) {
-        if (isLayer) {
-            clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
-        }
-        if (CC_LIKELY(isLayer || !properties().getHasOverlappingRendering())) {
-            // simply scale rendering content's alpha
-            canvasState.scaleAlpha(properties().getAlpha());
-        } else {
-            // savelayer needed to create an offscreen buffer
-            Rect layerBounds(0, 0, getWidth(), getHeight());
-            if (clipFlags) {
-                properties().getClippingRectForFlags(clipFlags, &layerBounds);
-                clipFlags = 0; // all clipping done by savelayer
-            }
-            LOG_ALWAYS_FATAL("TODO: savelayer");
-        }
-
-        if (CC_UNLIKELY(ATRACE_ENABLED() && properties().promotedToLayer())) {
-            // pretend alpha always causes savelayer to warn about
-            // performance problem affecting old versions
-            ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", getName(), getWidth(), getHeight());
-        }
-    }
-    if (clipFlags) {
-        Rect clipRect;
-        properties().getClippingRectForFlags(clipFlags, &clipRect);
-        canvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
-                SkRegion::kIntersect_Op);
-    }
-
-    // TODO: support nesting round rect clips
-    if (mProperties.getRevealClip().willClip()) {
-        Rect bounds;
-        mProperties.getRevealClip().getBounds(&bounds);
-        canvasState.setClippingRoundRect(allocator,
-                bounds, mProperties.getRevealClip().getRadius());
-    } else if (mProperties.getOutline().willClip()) {
-        canvasState.setClippingOutline(allocator, &(mProperties.getOutline()));
-    }
-    return !canvasState.quickRejectConservative(
-            0, 0, properties().getWidth(), properties().getHeight());
-}
-
 /*
  * For property operations, we pass a savecount of 0, since the operations aren't part of the
  * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index bae5ebe..83d1b58 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -187,9 +187,6 @@
 
     AnimatorManager& animators() { return mAnimatorManager; }
 
-    // Returns false if the properties dictate the subtree contained in this RenderNode won't render
-    bool applyViewProperties(CanvasState& canvasState, LinearAllocator& allocator) const;
-
     void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const;
 
     bool nothingToDraw() const {
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 0bd5b65..3952798 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -610,7 +610,6 @@
 
     bool fitsOnLayer() const {
         const DeviceInfo* deviceInfo = DeviceInfo::get();
-        LOG_ALWAYS_FATAL_IF(!deviceInfo, "DeviceInfo uninitialized");
         return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize()
                         && mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
     }
diff --git a/libs/hwui/unit_tests/OpReordererTests.cpp b/libs/hwui/unit_tests/OpReordererTests.cpp
index a8c9bba..07a1855 100644
--- a/libs/hwui/unit_tests/OpReordererTests.cpp
+++ b/libs/hwui/unit_tests/OpReordererTests.cpp
@@ -17,10 +17,10 @@
 #include <gtest/gtest.h>
 
 #include <BakedOpState.h>
+#include <LayerUpdateQueue.h>
 #include <OpReorderer.h>
 #include <RecordedOp.h>
 #include <RecordingCanvas.h>
-#include <renderthread/CanvasContext.h> // todo: remove
 #include <unit_tests/TestUtils.h>
 
 #include <unordered_map>
@@ -28,8 +28,8 @@
 namespace android {
 namespace uirenderer {
 
-LayerUpdateQueue sEmptyLayerUpdateQueue;
-Vector3 sLightCenter = {100, 100, 100};
+const LayerUpdateQueue sEmptyLayerUpdateQueue;
+const Vector3 sLightCenter = {100, 100, 100};
 
 static std::vector<sp<RenderNode>> createSyncedNodeList(sp<RenderNode>& node) {
     TestUtils::syncHierarchyPropertiesAndDisplayList(node);
@@ -79,7 +79,7 @@
 
 /**
  * Dispatches all static methods to similar formed methods on renderer, which fail by default but
- * are overriden by subclasses per test.
+ * are overridden by subclasses per test.
  */
 class TestDispatcher {
 public:
@@ -117,7 +117,6 @@
         canvas.drawBitmap(bitmap, 10, 10, nullptr);
     });
     OpReorderer reorderer(100, 200, *dl, sLightCenter);
-
     SimpleTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex()); // 2 ops + start + end
@@ -163,7 +162,6 @@
     });
 
     OpReorderer reorderer(200, 200, *dl, sLightCenter);
-
     SimpleBatchingTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2 * SIMPLE_BATCHING_LOOPS, renderer.getIndex()); // 2 x loops ops, because no merging (TODO: force no merging)
@@ -208,7 +206,6 @@
 
     OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
             createSyncedNodeList(parent), sLightCenter);
-
     RenderNodeTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
 }
@@ -232,7 +229,6 @@
     OpReorderer reorderer(sEmptyLayerUpdateQueue,
             SkRect::MakeLTRB(10, 20, 30, 40), // clip to small area, should see in receiver
             200, 200, createSyncedNodeList(node), sLightCenter);
-
     ClippedTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
 }
@@ -274,7 +270,6 @@
     });
 
     OpReorderer reorderer(200, 200, *dl, sLightCenter);
-
     SaveLayerSimpleTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
@@ -345,7 +340,6 @@
     });
 
     OpReorderer reorderer(800, 800, *dl, sLightCenter);
-
     SaveLayerNestedTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(10, renderer.getIndex());
@@ -520,7 +514,6 @@
 
     OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
             syncedList, sLightCenter);
-
     HwLayerComplexTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(13, renderer.getIndex());
@@ -570,7 +563,6 @@
     });
     OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100,
             createSyncedNodeList(parent), sLightCenter);
-
     ZReorderTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(10, renderer.getIndex());
@@ -616,7 +608,6 @@
 
     OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
             createSyncedNodeList(parent), sLightCenter);
-
     ShadowTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2, renderer.getIndex());
@@ -658,7 +649,6 @@
 
     OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
             createSyncedNodeList(parent), (Vector3) { 100, 100, 100 });
-
     ShadowSaveLayerTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(5, renderer.getIndex());
@@ -708,7 +698,6 @@
     layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(100, 100));
     OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
             syncedList, (Vector3) { 100, 100, 100 });
-
     ShadowHwLayerTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(5, renderer.getIndex());
@@ -738,13 +727,11 @@
 
     OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
             createSyncedNodeList(parent), sLightCenter);
-
     ShadowLayeringTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
 }
 
-
 static void testProperty(TestUtils::PropSetupCallback propSetupCallback,
         std::function<void(const RectOp&, const BakedOpState&)> opValidateCallback) {
     class PropertyTestRenderer : public TestRendererBase {
@@ -766,7 +753,6 @@
 
     OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 200, 200,
             createSyncedNodeList(node), sLightCenter);
-
     PropertyTestRenderer renderer(opValidateCallback);
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(1, renderer.getIndex()) << "Should have seen one op";
@@ -854,5 +840,128 @@
     });
 }
 
+struct SaveLayerAlphaData {
+    uint32_t layerWidth = 0;
+    uint32_t layerHeight = 0;
+    Rect rectClippedBounds;
+    Matrix4 rectMatrix;
+};
+/**
+ * Constructs a view to hit the temporary layer alpha property implementation:
+ *     a) 0 < alpha < 1
+ *     b) too big for layer (larger than maxTextureSize)
+ *     c) overlapping rendering content
+ * returning observed data about layer size and content clip/transform.
+ *
+ * Used to validate clipping behavior of temporary layer, where requested layer size is reduced
+ * (for efficiency, and to fit in layer size constraints) based on parent clip.
+ */
+void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData,
+        TestUtils::PropSetupCallback propSetupCallback) {
+    class SaveLayerAlphaClipTestRenderer : public TestRendererBase {
+    public:
+        SaveLayerAlphaClipTestRenderer(SaveLayerAlphaData* outData)
+                : mOutData(outData) {}
+
+        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
+            EXPECT_EQ(0, mIndex++);
+            mOutData->layerWidth = width;
+            mOutData->layerHeight = height;
+            return nullptr;
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
+
+            mOutData->rectClippedBounds = state.computedState.clippedBounds;
+            mOutData->rectMatrix = state.computedState.transform;
+        }
+        void endLayer() override {
+            EXPECT_EQ(2, mIndex++);
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(3, mIndex++);
+        }
+    private:
+        SaveLayerAlphaData* mOutData;
+    };
+
+    ASSERT_GT(10000, DeviceInfo::get()->maxTextureSize())
+            << "Node must be bigger than max texture size to exercise saveLayer codepath";
+    auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 10000, 10000, [](RecordingCanvas& canvas) {
+        SkPaint paint;
+        paint.setColor(SK_ColorWHITE);
+        canvas.drawRect(0, 0, 10000, 10000, paint);
+    }, [&propSetupCallback](RenderProperties& properties) {
+        properties.setHasOverlappingRendering(true);
+        properties.setAlpha(0.5f); // force saveLayer, since too big for HW layer
+
+        // apply other properties
+        int flags = propSetupCallback(properties);
+        return RenderNode::GENERIC | RenderNode::ALPHA | flags;
+    });
+    auto nodes = createSyncedNodeList(node); // sync before querying height
+
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, nodes, sLightCenter);
+    SaveLayerAlphaClipTestRenderer renderer(outObservedData);
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+
+    // assert, since output won't be valid if we haven't seen a save layer triggered
+    ASSERT_EQ(4, renderer.getIndex()) << "Test must trigger saveLayer alpha behavior.";
+}
+
+TEST(OpReorderer, renderPropSaveLayerAlphaClipBig) {
+    SaveLayerAlphaData observedData;
+    testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) {
+        properties.setTranslationX(10); // offset rendering content
+        properties.setTranslationY(-2000); // offset rendering content
+        return RenderNode::TRANSLATION_X | RenderNode::TRANSLATION_Y;
+    });
+    EXPECT_EQ(190u, observedData.layerWidth);
+    EXPECT_EQ(200u, observedData.layerHeight);
+    EXPECT_EQ(Rect(0, 0, 190, 200), observedData.rectClippedBounds)
+            << "expect content to be clipped to screen area";
+    Matrix4 expected;
+    expected.loadTranslate(0, -2000, 0);
+    EXPECT_MATRIX_APPROX_EQ(expected, observedData.rectMatrix)
+            << "expect content to be translated as part of being clipped";
+}
+
+TEST(OpReorderer, renderPropSaveLayerAlphaRotate) {
+    SaveLayerAlphaData observedData;
+    testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) {
+        // Translate and rotate the view so that the only visible part is the top left corner of
+        // the view. It will form an isoceles right triangle with a long side length of 200 at the
+        // bottom of the viewport.
+        properties.setTranslationX(100);
+        properties.setTranslationY(100);
+        properties.setPivotX(0);
+        properties.setPivotY(0);
+        properties.setRotation(45);
+        return RenderNode::GENERIC
+                | RenderNode::TRANSLATION_X | RenderNode::TRANSLATION_Y
+                | RenderNode::ROTATION;
+    });
+    // ceil(sqrt(2) / 2 * 200) = 142
+    EXPECT_EQ(142u, observedData.layerWidth);
+    EXPECT_EQ(142u, observedData.layerHeight);
+    EXPECT_EQ(Rect(0, 0, 142, 142), observedData.rectClippedBounds);
+    EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix);
+}
+
+TEST(OpReorderer, renderPropSaveLayerAlphaScale) {
+    SaveLayerAlphaData observedData;
+    testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) {
+        properties.setPivotX(0);
+        properties.setPivotY(0);
+        properties.setScaleX(2);
+        properties.setScaleY(0.5f);
+        return RenderNode::GENERIC | RenderNode::SCALE_X | RenderNode::SCALE_Y;
+    });
+    EXPECT_EQ(100u, observedData.layerWidth);
+    EXPECT_EQ(400u, observedData.layerHeight);
+    EXPECT_EQ(Rect(0, 0, 100, 400), observedData.rectClippedBounds);
+    EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix);
+}
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index c9586e4..bd6af78 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -86,6 +86,9 @@
     mLocked.pointerIconChanged = false;
     mLocked.requestedPointerShape = mPolicy->getDefaultPointerIconId();
 
+    mLocked.animationFrameIndex = 0;
+    mLocked.lastFrameUpdatedTime = 0;
+
     mLocked.buttonState = 0;
 
     loadResources();
@@ -239,7 +242,8 @@
     AutoMutex _l(mLock);
 
     if (presentation == PRESENTATION_POINTER && mLocked.additionalMouseResources.empty()) {
-        mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources);
+        mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
+                                              &mLocked.animationResources);
     }
 
     if (mLocked.presentation != presentation) {
@@ -402,7 +406,7 @@
     updatePointerLocked();
 }
 
-void PointerController::updatePointerShape(int iconId) {
+void PointerController::updatePointerShape(int32_t iconId) {
     AutoMutex _l(mLock);
     if (mLocked.requestedPointerShape != iconId) {
         mLocked.requestedPointerShape = iconId;
@@ -462,8 +466,17 @@
 void PointerController::doAnimate(nsecs_t timestamp) {
     AutoMutex _l(mLock);
 
-    bool keepAnimating = false;
     mLocked.animationPending = false;
+
+    bool keepFading = doFadingAnimationLocked(timestamp);
+    bool keepBitmapFlipping = doBitmapAnimationLocked(timestamp);
+    if (keepFading || keepBitmapFlipping) {
+        startAnimationLocked();
+    }
+}
+
+bool PointerController::doFadingAnimationLocked(nsecs_t timestamp) {
+    bool keepAnimating = false;
     nsecs_t frameDelay = timestamp - mLocked.animationTime;
 
     // Animate pointer fade.
@@ -501,10 +514,32 @@
             }
         }
     }
+    return keepAnimating;
+}
 
-    if (keepAnimating) {
-        startAnimationLocked();
+bool PointerController::doBitmapAnimationLocked(nsecs_t timestamp) {
+    std::map<int32_t, PointerAnimation>::const_iterator iter = mLocked.animationResources.find(
+            mLocked.requestedPointerShape);
+    if (iter == mLocked.animationResources.end()) {
+        return false;
     }
+
+    if (timestamp - mLocked.lastFrameUpdatedTime > iter->second.durationPerFrame) {
+        mSpriteController->openTransaction();
+
+        int incr = (timestamp - mLocked.lastFrameUpdatedTime) / iter->second.durationPerFrame;
+        mLocked.animationFrameIndex += incr;
+        mLocked.lastFrameUpdatedTime += iter->second.durationPerFrame * incr;
+        while (mLocked.animationFrameIndex >= iter->second.animationFrames.size()) {
+            mLocked.animationFrameIndex -= iter->second.animationFrames.size();
+        }
+        mLocked.pointerSprite->setIcon(iter->second.animationFrames[mLocked.animationFrameIndex]);
+
+        mSpriteController->closeTransaction();
+    }
+
+    // Keep animating.
+    return true;
 }
 
 void PointerController::doInactivityTimeout() {
@@ -549,9 +584,16 @@
             if (mLocked.requestedPointerShape == mPolicy->getDefaultPointerIconId()) {
                 mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
             } else {
-                std::map<int, SpriteIcon>::const_iterator iter =
+                std::map<int32_t, SpriteIcon>::const_iterator iter =
                     mLocked.additionalMouseResources.find(mLocked.requestedPointerShape);
                 if (iter != mLocked.additionalMouseResources.end()) {
+                    std::map<int32_t, PointerAnimation>::const_iterator anim_iter =
+                            mLocked.animationResources.find(mLocked.requestedPointerShape);
+                    if (anim_iter != mLocked.animationResources.end()) {
+                        mLocked.animationFrameIndex = 0;
+                        mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
+                        startAnimationLocked();
+                    }
                     mLocked.pointerSprite->setIcon(iter->second);
                 } else {
                     ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerShape);
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 6d840db..b6c01d2 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -20,6 +20,7 @@
 #include "SpriteController.h"
 
 #include <map>
+#include <vector>
 
 #include <ui/DisplayInfo.h>
 #include <input/Input.h>
@@ -30,8 +31,6 @@
 #include <utils/String8.h>
 #include <gui/DisplayEventReceiver.h>
 
-#include <SkBitmap.h>
-
 namespace android {
 
 /*
@@ -43,6 +42,11 @@
     SpriteIcon spotAnchor;
 };
 
+struct PointerAnimation {
+    std::vector<SpriteIcon> animationFrames;
+    nsecs_t durationPerFrame;
+};
+
 /*
  * Pointer controller policy interface.
  *
@@ -59,7 +63,8 @@
 
 public:
     virtual void loadPointerResources(PointerResources* outResources) = 0;
-    virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources) = 0;
+    virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
+            std::map<int32_t, PointerAnimation>* outAnimationResources) = 0;
     virtual int32_t getDefaultPointerIconId() = 0;
 };
 
@@ -98,7 +103,7 @@
             const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
     virtual void clearSpots();
 
-    void updatePointerShape(int iconId);
+    void updatePointerShape(int32_t iconId);
     void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
     void setPointerIcon(const SpriteIcon& icon);
     void setInactivityTimeout(InactivityTimeout inactivityTimeout);
@@ -145,6 +150,9 @@
         bool animationPending;
         nsecs_t animationTime;
 
+        size_t animationFrameIndex;
+        nsecs_t lastFrameUpdatedTime;
+
         int32_t displayWidth;
         int32_t displayHeight;
         int32_t displayOrientation;
@@ -162,7 +170,8 @@
         SpriteIcon pointerIcon;
         bool pointerIconChanged;
 
-        std::map<int, SpriteIcon> additionalMouseResources;
+        std::map<int32_t, SpriteIcon> additionalMouseResources;
+        std::map<int32_t, PointerAnimation> animationResources;
 
         int32_t requestedPointerShape;
 
@@ -178,6 +187,8 @@
     void handleMessage(const Message& message);
     int handleEvent(int fd, int events, void* data);
     void doAnimate(nsecs_t timestamp);
+    bool doFadingAnimationLocked(nsecs_t timestamp);
+    bool doBitmapAnimationLocked(nsecs_t timestamp);
     void doInactivityTimeout();
 
     void startAnimationLocked();
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 6bf5721..445ee6f 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -17,6 +17,8 @@
 package android.media;
 
 import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -128,6 +130,9 @@
     // use sLock to serialize the accesses.
     private static final Object sLock = new Object();
 
+    // Pattern to check non zero timestamp
+    private static final Pattern sNonZeroTimePattern = Pattern.compile(".*[1-9].*");
+
     /**
      * Reads Exif tags from the specified JPEG file.
      */
@@ -367,7 +372,8 @@
      */
     public long getDateTime() {
         String dateTimeString = mAttributes.get(TAG_DATETIME);
-        if (dateTimeString == null) return -1;
+        if (dateTimeString == null
+                || !sNonZeroTimePattern.matcher(dateTimeString).matches()) return -1;
 
         ParsePosition pos = new ParsePosition(0);
         try {
@@ -402,7 +408,9 @@
     public long getGpsDateTime() {
         String date = mAttributes.get(TAG_GPS_DATESTAMP);
         String time = mAttributes.get(TAG_GPS_TIMESTAMP);
-        if (date == null || time == null) return -1;
+        if (date == null || time == null
+                || (!sNonZeroTimePattern.matcher(date).matches()
+                && !sNonZeroTimePattern.matcher(time).matches())) return -1;
 
         String dateTimeString = date + ' ' + time;
 
diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml
index cf13374..f263af7 100644
--- a/packages/PrintSpooler/res/values-af/strings.xml
+++ b/packages/PrintSpooler/res/values-af/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Tweesydig"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Oriëntasie"</string>
     <string name="label_pages" msgid="7768589729282182230">"Bladsye"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Kies \'n drukker"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Al <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Omvang van <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"bv. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index 18c90f5..a93e0a9 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"ባለ ሁለት-ጎን"</string>
     <string name="label_orientation" msgid="2853142581990496477">"አቀማመጠ ገፅ"</string>
     <string name="label_pages" msgid="7768589729282182230">"ገፆች"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"አንድ አታሚ ይምረጡ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ሁሉም <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"የ<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ክልል"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ለምሳሌ፦ 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
index 2d87498c..c9a6a395 100644
--- a/packages/PrintSpooler/res/values-ar/strings.xml
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"الجانبان"</string>
     <string name="label_orientation" msgid="2853142581990496477">"الاتجاه"</string>
     <string name="label_pages" msgid="7768589729282182230">"الصفحات"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"اختر طابعة"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"جميع الصفحات وعددها <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"النطاق <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"على سبيل المثال، 1—5،8،11—13"</string>
diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
index c8ca06c..5aeb7bb 100644
--- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml
+++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"İkitərəfli"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Oriyentasiya"</string>
     <string name="label_pages" msgid="7768589729282182230">"Səhifələr"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Printer seçin"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Bütün <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> diapazonu"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"məsələn, 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml
index 7129cc1..93feea5 100644
--- a/packages/PrintSpooler/res/values-bg/strings.xml
+++ b/packages/PrintSpooler/res/values-bg/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Двустранно"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Ориентация"</string>
     <string name="label_pages" msgid="7768589729282182230">"Страници"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Избиране на принтер"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Всички <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Обхват от <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"напр. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
index ae0b01c..0eed9aa 100644
--- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml
+++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"দ্বিভুজ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"সজ্জা"</string>
     <string name="label_pages" msgid="7768589729282182230">"পৃষ্ঠাগুলি"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"একটি মুদ্রক নির্বাচন করুন"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"সমস্ত <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> এর পরিসর"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"যেমন, ১—৫,৮,১১—১৩"</string>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index d221c6c..03d3060 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"De dues cares"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientació"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pàgines"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Tria una impressora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Totes (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Interval de: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
index 5396b3e..414abf9 100644
--- a/packages/PrintSpooler/res/values-cs/strings.xml
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Oboustranně"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientace"</string>
     <string name="label_pages" msgid="7768589729282182230">"Stránky"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Vyberte tiskárnu"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Vše: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Rozsah: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"např. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
index 484d66f..893c991 100644
--- a/packages/PrintSpooler/res/values-da/strings.xml
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Tosidet"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Retning"</string>
     <string name="label_pages" msgid="7768589729282182230">"Sider"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Vælg en printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Alle <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Interval på <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"f.eks. 1-5,8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index c6323ef..f6f53ea 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Zweiseitig"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Ausrichtung"</string>
     <string name="label_pages" msgid="7768589729282182230">"Seiten"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Drucker auswählen"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Alle <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Auswahl von <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"z. B. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml
index 85923b7..10ddf62 100644
--- a/packages/PrintSpooler/res/values-el/strings.xml
+++ b/packages/PrintSpooler/res/values-el/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Δύο όψεων"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Προσανατολισμός"</string>
     <string name="label_pages" msgid="7768589729282182230">"Σελίδες"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Επιλέξτε εκτυπωτή"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Και οι <xliff:g id="PAGE_COUNT">%1$s</xliff:g> σελίδες"</string>
     <string name="template_page_range" msgid="428638530038286328">"Εύρος σελίδων από <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"π.χ. 1-5,8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml
index 5ac14a3..a540ac5 100644
--- a/packages/PrintSpooler/res/values-en-rAU/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Two-sided"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Select a printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"All <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Range of <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml
index 5ac14a3..a540ac5 100644
--- a/packages/PrintSpooler/res/values-en-rGB/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Two-sided"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Select a printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"All <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Range of <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml
index 5ac14a3..a540ac5 100644
--- a/packages/PrintSpooler/res/values-en-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Two-sided"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Select a printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"All <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Range of <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 1876ae1..8929aa8 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Ambos lados"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string>
     <string name="label_pages" msgid="7768589729282182230">"Páginas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Seleccionar una impresora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Todas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Rango de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"Ej.: 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index 14ed0d8..7cfd92a 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dos caras"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string>
     <string name="label_pages" msgid="7768589729282182230">"Páginas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Elige una impresora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Todas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervalo de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"p. ej.: 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml
index c2843321..ee93bcf 100644
--- a/packages/PrintSpooler/res/values-et-rEE/strings.xml
+++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Kahepoolne"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Suund"</string>
     <string name="label_pages" msgid="7768589729282182230">"Lehed"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Printeri valimine"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Kõik <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Vahemik <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"nt 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index eab7587..882e888 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Bi aldekoa"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientazioa"</string>
     <string name="label_pages" msgid="7768589729282182230">"Orriak"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Hautatu inprimagailua"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> orriak"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> orriko tartea"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"adib., 1-5, 8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 156eb47..10743e7 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"دوطرفه"</string>
     <string name="label_orientation" msgid="2853142581990496477">"جهت"</string>
     <string name="label_pages" msgid="7768589729282182230">"صفحه‌ها"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"چاپگری انتخاب کنید"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"همه <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
     <string name="template_page_range" msgid="428638530038286328">"محدوده <xliff:g id="PAGE_COUNT">%1$s</xliff:g> صفحه"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"‏‏‎مثلاً ۱—۵،‏۹،۷—۱۰"</string>
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
index 887d428..ee35c41 100644
--- a/packages/PrintSpooler/res/values-fi/strings.xml
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Kaksipuolinen"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Suunta"</string>
     <string name="label_pages" msgid="7768589729282182230">"Sivut"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Valitse tulostin"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Kaikki <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Sivumäärä: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"esim. 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index a97b20a..eb99441 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Recto verso"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Sélectionnez une imprimante"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Toutes (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Plage de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index 726915b..c0eecfb 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Recto verso"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Sélect. imprimante"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Toutes (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Plage de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ex. : 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml
index 6a2d031..b4a1ec6 100644
--- a/packages/PrintSpooler/res/values-gl-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dual"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string>
     <string name="label_pages" msgid="7768589729282182230">"Páxinas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Escoller impresora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"As <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervalo de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ex.: 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
index 3b3d2ed..8f77953 100644
--- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"દ્વિભુજ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ઓરિએન્ટેશન"</string>
     <string name="label_pages" msgid="7768589729282182230">"પૃષ્ઠો"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"પ્રિન્ટર પસંદ કરો"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"તમામ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ની શ્રેણી"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"દા.ત. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index 162f65b..4c11323 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"दो-तरफ़ा"</string>
     <string name="label_orientation" msgid="2853142581990496477">"अभिविन्‍यास"</string>
     <string name="label_pages" msgid="7768589729282182230">"पृष्ठ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"कोई प्रिंटर चुनें"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"सभी <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"पृष्ठ संख्या <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"उदा. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
index 9276300..4cec3ba 100644
--- a/packages/PrintSpooler/res/values-hr/strings.xml
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Obostrano"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orijentacija"</string>
     <string name="label_pages" msgid="7768589729282182230">"Stranice"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Odaberite pisač"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Sve stranice (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Raspon od <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"npr. 1 – 5,8,11 – 13"</string>
diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml
index ca48f9a..ac1ba6e 100644
--- a/packages/PrintSpooler/res/values-hu/strings.xml
+++ b/packages/PrintSpooler/res/values-hu/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Kétoldalas"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Tájolás"</string>
     <string name="label_pages" msgid="7768589729282182230">"Oldalak"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Válasszon ki egy nyomtatót"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Összes (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> oldalas tartomány"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"pl. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
index a198277..dda6745 100644
--- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Երկկողմանի"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Դիրքավորում"</string>
     <string name="label_pages" msgid="7768589729282182230">"Էջեր"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Ընտրել տպիչ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Բոլորը՝ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Միջակայքը՝ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"օր.՝ 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
index 5050700..b203e2b 100644
--- a/packages/PrintSpooler/res/values-in/strings.xml
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Bersisi ganda"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientasi"</string>
     <string name="label_pages" msgid="7768589729282182230">"Halaman"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Pilih printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Semua dari <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Rentang dari <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"misalnya 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml
index 33f10f5..6dfdabc 100644
--- a/packages/PrintSpooler/res/values-is-rIS/strings.xml
+++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Tvíhliða"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Stefna"</string>
     <string name="label_pages" msgid="7768589729282182230">"Síður"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Veldu prentara"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Allar <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"t.d. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index f7c6eff..fd5473a 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Con doppia funzione"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientamento"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pagine"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Seleziona stampante"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Tutte e <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervallo di <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"Es.: 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index 545ba88..dd062a3 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"דו-צדדי"</string>
     <string name="label_orientation" msgid="2853142581990496477">"כיוון"</string>
     <string name="label_pages" msgid="7768589729282182230">"עמודים"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"בחר מדפסת"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"הכל <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"טווח של <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"למשל 1–5‏,8,‏11–13"</string>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
index e292013..23e4809 100644
--- a/packages/PrintSpooler/res/values-ja/strings.xml
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"両面"</string>
     <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
     <string name="label_pages" msgid="7768589729282182230">"ページ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"プリンタを選択"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>ページすべて"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>ページ分"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"例: 1-5,8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
index db71506..9f86f05 100644
--- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"ორმხრივი"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ორიენტაცია"</string>
     <string name="label_pages" msgid="7768589729282182230">"გვერდები"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"პრინტერის არჩევა"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ყველა <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>-ის არეალი"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"მაგ. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index de2115a..05c300e 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Екі жақты"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Бағыты"</string>
     <string name="label_pages" msgid="7768589729282182230">"Беттер"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Принтерді таңдау"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Барлық <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ауқымы"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"мысалы, 1—5,8,11—13"</string>
@@ -60,8 +61,7 @@
     </plurals>
     <string name="choose_print_service" msgid="3740309762324459694">"Принтер қызметін таңдау"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтерлерді іздеу"</string>
-    <!-- no translation found for print_no_print_services (8561247706423327966) -->
-    <skip />
+    <string name="print_no_print_services" msgid="8561247706423327966">"Басып шығару қызметтері қосылмаған"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Ешқандай принтер табылмады"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басып шығарылуда"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> жұмысын тоқтатуда"</string>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index c91e6ae..0861e59 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"សងខាង"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ទិស"</string>
     <string name="label_pages" msgid="7768589729282182230">"ទំព័រ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ជ្រើសម៉ាស៊ីនបោះពុម្ព"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ទាំងអស់"</string>
     <string name="template_page_range" msgid="428638530038286328">"ជួរ​នៃ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ឧ. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index 86dc11f..71b098d 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"ಎರಡು ಬದಿ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ಓರಿಯಂಟೇಶನ್"</string>
     <string name="label_pages" msgid="7768589729282182230">"ಪುಟಗಳು"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ಪ್ರಿಂಟರ್ ಆಯ್ಕೆ ಮಾಡಿ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ಎಲ್ಲಾ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ನ ಶ್ರೇಣಿ"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ಉದಾ. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml
index 4450bca..451ab58 100644
--- a/packages/PrintSpooler/res/values-ko/strings.xml
+++ b/packages/PrintSpooler/res/values-ko/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"양면"</string>
     <string name="label_orientation" msgid="2853142581990496477">"방향"</string>
     <string name="label_pages" msgid="7768589729282182230">"페이지"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"프린터 선택"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>페이지 모두"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>페이지 범위"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"예: 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index b4bdc57..98da08c 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Эки тараптуу"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Багыттоо"</string>
     <string name="label_pages" msgid="7768589729282182230">"Баракчалар"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Принтер тандаңыз"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Бардыгы <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> аралыгы"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"мис. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
index 500f01c..2029fdf 100644
--- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"ສອງ​ດ້ານ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ລວງ"</string>
     <string name="label_pages" msgid="7768589729282182230">"ໜ້າ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ເລືອກເຄື່ອງພິມ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ທັງ​ໝົດ <xliff:g id="PAGE_COUNT">%1$s</xliff:g> ໜ້າ"</string>
     <string name="template_page_range" msgid="428638530038286328">"ໄລ​ຍະ <xliff:g id="PAGE_COUNT">%1$s</xliff:g> ໜ້າ"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ຕົວຢ່າງ: 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml
index ad59182..972abb5 100644
--- a/packages/PrintSpooler/res/values-lt/strings.xml
+++ b/packages/PrintSpooler/res/values-lt/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dvipusis"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientacija"</string>
     <string name="label_pages" msgid="7768589729282182230">"Puslapiai"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Spausdint. pasirink."</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Visi <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Diapazonas: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"pvz., 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml
index 3b30d04..f565b23 100644
--- a/packages/PrintSpooler/res/values-lv/strings.xml
+++ b/packages/PrintSpooler/res/values-lv/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Divpusējs"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Virziens"</string>
     <string name="label_pages" msgid="7768589729282182230">"Lapas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Atlasīt printeri"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Visas <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Diapazons: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"piem., 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
index 42548fc..f5c06d1 100644
--- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml
+++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Двостран"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Ориентација"</string>
     <string name="label_pages" msgid="7768589729282182230">"Страници"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Избери печатач"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Сите <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Опсег од <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"на пр.: 1-5,8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
index 4e5a99c..2d45ce5 100644
--- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"രണ്ട് വശങ്ങളുള്ളത്"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ഓറിയന്‍റേഷന്‍‌"</string>
     <string name="label_pages" msgid="7768589729282182230">"പേജുകൾ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ഒരു പ്രിന്റർ തിരഞ്ഞെടുക്കുക"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"എല്ലാ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> എന്നതിന്റെ പരിധി"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ഉദാ. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
index 0f49671..f2c7b73 100644
--- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml
+++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Хоёр талт"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Чиглэл"</string>
     <string name="label_pages" msgid="7768589729282182230">"Хуудас"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Хэвлэгчийг сонгоно уу"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Нийт <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Хүрээ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ж.нь. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
index 53225ee..1c079dc 100644
--- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"दोन्ही बाजूंनी"</string>
     <string name="label_orientation" msgid="2853142581990496477">"अभिमुखता"</string>
     <string name="label_pages" msgid="7768589729282182230">"पृष्ठे"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"प्रिंटर निवडा"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"सर्व <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ची श्रेणी"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"उदा. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
index a15587b..d6b5ea7 100644
--- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dua sisi"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientasi"</string>
     <string name="label_pages" msgid="7768589729282182230">"Halaman"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Pilih pencetak"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Semua <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Julat <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"cth. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml
index 10dc93a..c3dc490 100644
--- a/packages/PrintSpooler/res/values-my-rMM/strings.xml
+++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"နှစ်ဖက်လှ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"အနေအထား"</string>
     <string name="label_pages" msgid="7768589729282182230">"စာမျက်နှာများ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ပုံနှိပ်စက်ကို ရွေးပါ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"အားလုံး <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>ဘောင် ထဲမှာ"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ဥပမာ ၁-၅၊ ၈၊ ၁၁-၁၃"</string>
diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml
index 8cbcee7..945bbea 100644
--- a/packages/PrintSpooler/res/values-nb/strings.xml
+++ b/packages/PrintSpooler/res/values-nb/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Tosidig"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Retning"</string>
     <string name="label_pages" msgid="7768589729282182230">"Sider"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Velg en skriver"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Alle <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Område på <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"f.eks. 1–5, 8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index ad9b4e3..34c1dd4f 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -27,6 +27,8 @@
     <string name="label_duplex" msgid="5370037254347072243">"दुई-पक्षीय"</string>
     <string name="label_orientation" msgid="2853142581990496477">"अभिमुखिकरण"</string>
     <string name="label_pages" msgid="7768589729282182230">"पृष्ठहरू"</string>
+    <!-- no translation found for destination_default_text (5422708056807065710) -->
+    <skip />
     <string name="template_all_pages" msgid="3322235982020148762">"सबै <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> को सीमा"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"उदाहरण १-५,८,११-१३"</string>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index bb8391e..76c8656 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dubbelzijdig"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Stand"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pagina\'s"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Printer selecteren"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Alle <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Bereik van <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"bijv. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
index aede004..45fa460 100644
--- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"ਦੋ-ਪਾਸੇ ਦਾ"</string>
     <string name="label_orientation" msgid="2853142581990496477">"ਅਨੁਕੂਲਨ"</string>
     <string name="label_pages" msgid="7768589729282182230">"ਸਫ਼ੇ"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ਇੱਕ ਪ੍ਰਿੰਟਰ ਚੁਣੋ"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ਸਾਰੇ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> ਦੀ ਰੇਂਜ"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ਉਦਾਹਰਨ ਲਈ 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml
index 4e20eed..df3ee924 100644
--- a/packages/PrintSpooler/res/values-pl/strings.xml
+++ b/packages/PrintSpooler/res/values-pl/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dwustronny"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientacja"</string>
     <string name="label_pages" msgid="7768589729282182230">"Strony"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Wybierz drukarkę"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Wszystkie <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Zakres <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"np. 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
index 7ab0f0a..90da72b 100644
--- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dois lados"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string>
     <string name="label_pages" msgid="7768589729282182230">"Páginas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Selec. impressora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Todas as <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervalo de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"Ex.: 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index 583052a..99bbd81 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dois lados"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string>
     <string name="label_pages" msgid="7768589729282182230">"Páginas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Selec. impressora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Todas as <xliff:g id="PAGE_COUNT">%1$s</xliff:g> páginas"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervalo de <xliff:g id="PAGE_COUNT">%1$s</xliff:g> pág."</string>
     <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
index 7ab0f0a..90da72b 100644
--- a/packages/PrintSpooler/res/values-pt/strings.xml
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dois lados"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string>
     <string name="label_pages" msgid="7768589729282182230">"Páginas"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Selec. impressora"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Todas as <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervalo de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"Ex.: 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
index 2769aae..4cfb8ab 100644
--- a/packages/PrintSpooler/res/values-ro/strings.xml
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Față-verso"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientare"</string>
     <string name="label_pages" msgid="7768589729282182230">"Pagini"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Selectați imprimanta"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Toate cele <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervalul de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"de ex. 1-5, 8, 11-13"</string>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
index c3cfac0..fb49330 100644
--- a/packages/PrintSpooler/res/values-ru/strings.xml
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Двусторонний"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Ориентация"</string>
     <string name="label_pages" msgid="7768589729282182230">"Страницы"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Выберите принтер"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Все <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Диапазон <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"напр., 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index 0e20705..fb6f145 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"පැති-දෙකක"</string>
     <string name="label_orientation" msgid="2853142581990496477">"දිශානතිය"</string>
     <string name="label_pages" msgid="7768589729282182230">"පිටු"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"මුද්‍රණ යන්ත්‍රයක් තෝරන්න"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"සියලුම <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> පරාසය"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"උ.දා. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
index b8d2167..605237b 100644
--- a/packages/PrintSpooler/res/values-sk/strings.xml
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Obojstranné"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientácia"</string>
     <string name="label_pages" msgid="7768589729282182230">"Strany"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Výber tlačiarne"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Všetky: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Rozsah: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"napr. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml
index a320e79b..48d2e1d 100644
--- a/packages/PrintSpooler/res/values-sl/strings.xml
+++ b/packages/PrintSpooler/res/values-sl/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dvostransko"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Postavitev"</string>
     <string name="label_pages" msgid="7768589729282182230">"Strani"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Izberite tiskalnik"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Vse (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Obseg strani: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"npr. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
index 177b282..5ba72ff 100644
--- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml
+++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Në dy anë"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientimi"</string>
     <string name="label_pages" msgid="7768589729282182230">"Faqe"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Zgjidh një printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Të <xliff:g id="PAGE_COUNT">%1$s</xliff:g> faqet"</string>
     <string name="template_page_range" msgid="428638530038286328">"Gama e faqeve: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"p.sh. 1 - 5,8,11 - 13"</string>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index f686e6d..7a04b8d 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Двострано"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Положај"</string>
     <string name="label_pages" msgid="7768589729282182230">"Странице"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Изаберите штампач"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Све странице (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"Опсег од <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"нпр. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml
index 6e176f03..ec4ad30 100644
--- a/packages/PrintSpooler/res/values-sv/strings.xml
+++ b/packages/PrintSpooler/res/values-sv/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Dubbelsidig"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Orientering"</string>
     <string name="label_pages" msgid="7768589729282182230">"Sidor"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Välj skrivare"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Alla <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Intervall på <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"t.ex. 1–5,8,11–13"</string>
diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml
index 8ce9190..eed3356 100644
--- a/packages/PrintSpooler/res/values-sw/strings.xml
+++ b/packages/PrintSpooler/res/values-sw/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Yenye pande mbili"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Mkao"</string>
     <string name="label_pages" msgid="7768589729282182230">"Kurasa"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Chagua printa"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Kurasa zote <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Mfululizo wa <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"k.m. 1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
index 486ddca..a9879c3 100644
--- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"இரு பக்க முறை"</string>
     <string name="label_orientation" msgid="2853142581990496477">"திசையமைப்பு"</string>
     <string name="label_pages" msgid="7768589729282182230">"பக்கங்கள்"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"பிரிண்டரை தேர்ந்தெடு"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"எல்லாம்: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"வரம்பில்: <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"எ.கா. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml
index f0f7e07..909cb90 100644
--- a/packages/PrintSpooler/res/values-te-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"రెండు వైపుల"</string>
     <string name="label_orientation" msgid="2853142581990496477">"దృగ్విన్యాసం"</string>
     <string name="label_pages" msgid="7768589729282182230">"పేజీలు"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ప్రింటర్ ఎంచుకోండి"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"మొత్తం <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> పరిధి"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ఉదా. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
index d3ef7c6..c33a759 100644
--- a/packages/PrintSpooler/res/values-th/strings.xml
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"2 ด้าน"</string>
     <string name="label_orientation" msgid="2853142581990496477">"การวางแนว"</string>
     <string name="label_pages" msgid="7768589729282182230">"หน้า"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"เลือกเครื่องพิมพ์"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"ทั้ง <xliff:g id="PAGE_COUNT">%1$s</xliff:g> หน้า"</string>
     <string name="template_page_range" msgid="428638530038286328">"ช่วง <xliff:g id="PAGE_COUNT">%1$s</xliff:g> หน้า"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"เช่น 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
index 061eeb9..545bda4 100644
--- a/packages/PrintSpooler/res/values-tl/strings.xml
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Two-sided"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Oryentasyon"</string>
     <string name="label_pages" msgid="7768589729282182230">"Mga Page"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Pumili ng printer"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Lahat ng <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Hanay ng <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"hal. 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
index db203ae..a13f2df 100644
--- a/packages/PrintSpooler/res/values-tr/strings.xml
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Çift taraflı"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Sayfa yönü"</string>
     <string name="label_pages" msgid="7768589729282182230">"Sayfa"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Yazıcı seçin"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> sayfanın tamamı"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> sayfalık aralık"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ör. 1-5,8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml
index 09c0555..def21ab 100644
--- a/packages/PrintSpooler/res/values-uk/strings.xml
+++ b/packages/PrintSpooler/res/values-uk/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Двосторонній друк"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Орієнтація"</string>
     <string name="label_pages" msgid="7768589729282182230">"Сторінки"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Виберіть принтер"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Усі <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Діапазон <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"напр.,1–5, 8, 11–13"</string>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index 44ca82b..c031aba 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"دو طرف"</string>
     <string name="label_orientation" msgid="2853142581990496477">"سمت بندی"</string>
     <string name="label_pages" msgid="7768589729282182230">"صفحات"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"ایک پرنٹر منتخب کریں"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"سبھی <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> کی رینج"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"‏مثلاً ‎1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index 477e424..9d615fb 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Ikki tomonlama"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Joylashuv"</string>
     <string name="label_pages" msgid="7768589729282182230">"Sahifalar"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Printer tanlash"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Barchasi (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="template_page_range" msgid="428638530038286328">"O‘zgarish chegarasi (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"masalan: 1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
index 3428ec7..0167823 100644
--- a/packages/PrintSpooler/res/values-vi/strings.xml
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Hai mặt"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Hướng"</string>
     <string name="label_pages" msgid="7768589729282182230">"Trang"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Chọn máy in"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Tất cả <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Phạm vi <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"Ví dụ: 1—5, 8, 11—13"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
index d1be250..f2b304a 100644
--- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -27,6 +27,8 @@
     <string name="label_duplex" msgid="5370037254347072243">"双面"</string>
     <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
     <string name="label_pages" msgid="7768589729282182230">"页数"</string>
+    <!-- no translation found for destination_default_text (5422708056807065710) -->
+    <skip />
     <string name="template_all_pages" msgid="3322235982020148762">"全部<xliff:g id="PAGE_COUNT">%1$s</xliff:g>页"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>页"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"例如:1-5、8、11-13"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
index bca0612..35643f3 100644
--- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"雙面"</string>
     <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
     <string name="label_pages" msgid="7768589729282182230">"頁數"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"選擇打印機"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"全部 <xliff:g id="PAGE_COUNT">%1$s</xliff:g> 頁"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> 頁"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"例如:1-5,8,11-13"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index c345252..40c44ff 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"雙面"</string>
     <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
     <string name="label_pages" msgid="7768589729282182230">"頁面"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"選取印表機"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"全部 <xliff:g id="PAGE_COUNT">%1$s</xliff:g> 頁"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> 頁"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"例如:1—5,8,11—13"</string>
diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml
index 7ba8950..e0f6f34 100644
--- a/packages/PrintSpooler/res/values-zu/strings.xml
+++ b/packages/PrintSpooler/res/values-zu/strings.xml
@@ -27,6 +27,7 @@
     <string name="label_duplex" msgid="5370037254347072243">"Inezinhlangothi ezimbili"</string>
     <string name="label_orientation" msgid="2853142581990496477">"Umumo"</string>
     <string name="label_pages" msgid="7768589729282182230">"Amakhasi"</string>
+    <string name="destination_default_text" msgid="5422708056807065710">"Khetha iphrinta"</string>
     <string name="template_all_pages" msgid="3322235982020148762">"Konke <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"Ibanga le-<xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"isb. 1—5, 8, 11—13"</string>
@@ -60,7 +61,7 @@
     </plurals>
     <string name="choose_print_service" msgid="3740309762324459694">"Khetha isevisi yephrinta"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Isesha amaphrinta"</string>
-    <string name="print_no_print_services" msgid="8561247706423327966">"Awekho amasevisi okuphrinta enikwe amandla"</string>
+    <string name="print_no_print_services" msgid="8561247706423327966">"Amasevisi ephrinta akavuliwe."</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Awekho amaphrinta atholiwe"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Iphrinta i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ikhansela i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/accounts/AuthenticatorHelper.java b/packages/SettingsLib/src/com/android/settingslib/accounts/AuthenticatorHelper.java
new file mode 100644
index 0000000..ef511bb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/accounts/AuthenticatorHelper.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settingslib.accounts;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SyncAdapterType;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper class for monitoring accounts on the device for a given user.
+ *
+ * Classes using this helper should implement {@link OnAccountsUpdateListener}.
+ * {@link OnAccountsUpdateListener#onAccountsUpdate(UserHandle)} will then be
+ * called once accounts get updated. For setting up listening for account
+ * updates, {@link #listenToAccountUpdates()} and
+ * {@link #stopListeningToAccountUpdates()} should be used.
+ */
+final public class AuthenticatorHelper extends BroadcastReceiver {
+    private static final String TAG = "AuthenticatorHelper";
+
+    private final Map<String, AuthenticatorDescription> mTypeToAuthDescription = new HashMap<>();
+    private final ArrayList<String> mEnabledAccountTypes = new ArrayList<>();
+    private final Map<String, Drawable> mAccTypeIconCache = new HashMap<>();
+    private final HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = new HashMap<>();
+
+    private final UserHandle mUserHandle;
+    private final Context mContext;
+    private final OnAccountsUpdateListener mListener;
+    private boolean mListeningToAccountUpdates;
+
+    public interface OnAccountsUpdateListener {
+        void onAccountsUpdate(UserHandle userHandle);
+    }
+
+    public AuthenticatorHelper(Context context, UserHandle userHandle,
+            OnAccountsUpdateListener listener) {
+        mContext = context;
+        mUserHandle = userHandle;
+        mListener = listener;
+        // This guarantees that the helper is ready to use once constructed: the account types and
+        // authorities are initialized
+        onAccountsUpdated(null);
+    }
+
+    public String[] getEnabledAccountTypes() {
+        return mEnabledAccountTypes.toArray(new String[mEnabledAccountTypes.size()]);
+    }
+
+    public void preloadDrawableForType(final Context context, final String accountType) {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                getDrawableForType(context, accountType);
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+    }
+
+    /**
+     * Gets an icon associated with a particular account type. If none found, return null.
+     * @param accountType the type of account
+     * @return a drawable for the icon or a default icon returned by
+     * {@link PackageManager#getDefaultActivityIcon} if one cannot be found.
+     */
+    public Drawable getDrawableForType(Context context, final String accountType) {
+        Drawable icon = null;
+        synchronized (mAccTypeIconCache) {
+            if (mAccTypeIconCache.containsKey(accountType)) {
+                return mAccTypeIconCache.get(accountType);
+            }
+        }
+        if (mTypeToAuthDescription.containsKey(accountType)) {
+            try {
+                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+                Context authContext = context.createPackageContextAsUser(desc.packageName, 0,
+                        mUserHandle);
+                icon = mContext.getPackageManager().getUserBadgedIcon(
+                        authContext.getDrawable(desc.iconId), mUserHandle);
+                synchronized (mAccTypeIconCache) {
+                    mAccTypeIconCache.put(accountType, icon);
+                }
+            } catch (PackageManager.NameNotFoundException|Resources.NotFoundException e) {
+                // Ignore
+            }
+        }
+        if (icon == null) {
+            icon = context.getPackageManager().getDefaultActivityIcon();
+        }
+        return icon;
+    }
+
+    /**
+     * Gets the label associated with a particular account type. If none found, return null.
+     * @param accountType the type of account
+     * @return a CharSequence for the label or null if one cannot be found.
+     */
+    public CharSequence getLabelForType(Context context, final String accountType) {
+        CharSequence label = null;
+        if (mTypeToAuthDescription.containsKey(accountType)) {
+            try {
+                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+                Context authContext = context.createPackageContextAsUser(desc.packageName, 0,
+                        mUserHandle);
+                label = authContext.getResources().getText(desc.labelId);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "No label name for account type " + accountType);
+            } catch (Resources.NotFoundException e) {
+                Log.w(TAG, "No label icon for account type " + accountType);
+            }
+        }
+        return label;
+    }
+
+    /**
+     * Gets the package associated with a particular account type. If none found, return null.
+     * @param accountType the type of account
+     * @return the package name or null if one cannot be found.
+     */
+    public String getPackageForType(final String accountType) {
+        if (mTypeToAuthDescription.containsKey(accountType)) {
+            AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+            return desc.packageName;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the resource id of the label associated with a particular account type. If none found,
+     * return -1.
+     * @param accountType the type of account
+     * @return a resource id for the label or -1 if none found;
+     */
+    public int getLabelIdForType(final String accountType) {
+        if (mTypeToAuthDescription.containsKey(accountType)) {
+            AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+            return desc.labelId;
+        }
+        return -1;
+    }
+
+    /**
+     * Updates provider icons. Subclasses should call this in onCreate()
+     * and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
+     */
+    public void updateAuthDescriptions(Context context) {
+        AuthenticatorDescription[] authDescs = AccountManager.get(context)
+                .getAuthenticatorTypesAsUser(mUserHandle.getIdentifier());
+        for (int i = 0; i < authDescs.length; i++) {
+            mTypeToAuthDescription.put(authDescs[i].type, authDescs[i]);
+        }
+    }
+
+    public boolean containsAccountType(String accountType) {
+        return mTypeToAuthDescription.containsKey(accountType);
+    }
+
+    public AuthenticatorDescription getAccountTypeDescription(String accountType) {
+        return mTypeToAuthDescription.get(accountType);
+    }
+
+    public boolean hasAccountPreferences(final String accountType) {
+        if (containsAccountType(accountType)) {
+            AuthenticatorDescription desc = getAccountTypeDescription(accountType);
+            if (desc != null && desc.accountPreferencesId != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void onAccountsUpdated(Account[] accounts) {
+        updateAuthDescriptions(mContext);
+        if (accounts == null) {
+            accounts = AccountManager.get(mContext).getAccountsAsUser(mUserHandle.getIdentifier());
+        }
+        mEnabledAccountTypes.clear();
+        mAccTypeIconCache.clear();
+        for (int i = 0; i < accounts.length; i++) {
+            final Account account = accounts[i];
+            if (!mEnabledAccountTypes.contains(account.type)) {
+                mEnabledAccountTypes.add(account.type);
+            }
+        }
+        buildAccountTypeToAuthoritiesMap();
+        if (mListeningToAccountUpdates) {
+            mListener.onAccountsUpdate(mUserHandle);
+        }
+    }
+
+    @Override
+    public void onReceive(final Context context, final Intent intent) {
+        // TODO: watch for package upgrades to invalidate cache; see http://b/7206643
+        final Account[] accounts = AccountManager.get(mContext)
+                .getAccountsAsUser(mUserHandle.getIdentifier());
+        onAccountsUpdated(accounts);
+    }
+
+    public void listenToAccountUpdates() {
+        if (!mListeningToAccountUpdates) {
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
+            // At disk full, certain actions are blocked (such as writing the accounts to storage).
+            // It is useful to also listen for recovery from disk full to avoid bugs.
+            intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+            mContext.registerReceiverAsUser(this, mUserHandle, intentFilter, null, null);
+            mListeningToAccountUpdates = true;
+        }
+    }
+
+    public void stopListeningToAccountUpdates() {
+        if (mListeningToAccountUpdates) {
+            mContext.unregisterReceiver(this);
+            mListeningToAccountUpdates = false;
+        }
+    }
+
+    public ArrayList<String> getAuthoritiesForAccountType(String type) {
+        return mAccountTypeToAuthorities.get(type);
+    }
+
+    private void buildAccountTypeToAuthoritiesMap() {
+        mAccountTypeToAuthorities.clear();
+        SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
+                mUserHandle.getIdentifier());
+        for (int i = 0, n = syncAdapters.length; i < n; i++) {
+            final SyncAdapterType sa = syncAdapters[i];
+            ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
+            if (authorities == null) {
+                authorities = new ArrayList<String>();
+                mAccountTypeToAuthorities.put(sa.accountType, authorities);
+            }
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "Added authority " + sa.authority + " to accountType "
+                        + sa.accountType);
+            }
+            authorities.add(sa.authority);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java b/packages/SettingsLib/src/com/android/settingslib/net/MobileDataController.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
rename to packages/SettingsLib/src/com/android/settingslib/net/MobileDataController.java
index a7fdadc..642b60e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataControllerImpl.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/MobileDataController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
-
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-import static android.telephony.TelephonyManager.SIM_STATE_READY;
-import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
-import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
+package com.android.settingslib.net;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
@@ -42,7 +35,14 @@
 import java.util.Date;
 import java.util.Locale;
 
-public class MobileDataControllerImpl implements NetworkController.MobileDataController {
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
+import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
+import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
+import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
+
+public class MobileDataController {
     private static final String TAG = "MobileDataController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -60,9 +60,9 @@
 
     private INetworkStatsSession mSession;
     private Callback mCallback;
-    private NetworkControllerImpl mNetworkController;
+    private NetworkNameProvider mNetworkController;
 
-    public MobileDataControllerImpl(Context context) {
+    public MobileDataController(Context context) {
         mContext = context;
         mTelephonyManager = TelephonyManager.from(context);
         mConnectivityManager = ConnectivityManager.from(context);
@@ -71,7 +71,7 @@
         mPolicyManager = NetworkPolicyManager.from(mContext);
     }
 
-    public void setNetworkController(NetworkControllerImpl networkController) {
+    public void setNetworkController(NetworkNameProvider networkController) {
         mNetworkController = networkController;
     }
 
@@ -161,7 +161,7 @@
             } else {
                 usage.warningLevel = DEFAULT_WARNING_LEVEL;
             }
-            if (usage != null) {
+            if (usage != null && mNetworkController != null) {
                 usage.carrier = mNetworkController.getMobileDataNetworkName();
             }
             return usage;
@@ -231,6 +231,18 @@
         }
     }
 
+    public interface NetworkNameProvider {
+        String getMobileDataNetworkName();
+    }
+
+    public static class DataUsageInfo {
+        public String carrier;
+        public String period;
+        public long limitLevel;
+        public long warningLevel;
+        public long usageLevel;
+    }
+
     public interface Callback {
         void onMobileDataEnabled(boolean enabled);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/AnimatedImageView.java b/packages/SettingsLib/src/com/android/settingslib/widget/AnimatedImageView.java
new file mode 100644
index 0000000..f5e39be
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/AnimatedImageView.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settingslib.widget;
+
+import android.content.Context;
+import android.graphics.drawable.AnimatedRotateDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+
+public class AnimatedImageView extends ImageView {
+    private AnimatedRotateDrawable mDrawable;
+    private boolean mAnimating;
+
+    public AnimatedImageView(Context context) {
+        super(context);
+    }
+
+    public AnimatedImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    private void updateDrawable() {
+        if (isShown() && mDrawable != null) {
+            mDrawable.stop();
+        }
+        final Drawable drawable = getDrawable();
+        if (drawable instanceof AnimatedRotateDrawable) {
+            mDrawable = (AnimatedRotateDrawable) drawable;
+            // TODO: define in drawable xml once we have public attrs.
+            mDrawable.setFramesCount(56);
+            mDrawable.setFramesDuration(32);
+            if (isShown() && mAnimating) {
+                mDrawable.start();
+            }
+        } else {
+            mDrawable = null;
+        }
+    }
+
+    private void updateAnimating() {
+        if (mDrawable != null) {
+            if (isShown() && mAnimating) {
+                mDrawable.start();
+            } else {
+                mDrawable.stop();
+            }
+        }
+    }
+
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        super.setImageDrawable(drawable);
+        updateDrawable();
+    }
+
+    @Override
+    public void setImageResource(int resid) {
+        super.setImageResource(resid);
+        updateDrawable();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateAnimating();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        updateAnimating();
+    }
+
+    public void setAnimating(boolean animating) {
+        mAnimating = animating;
+        updateAnimating();
+    }
+
+    @Override
+    protected void onVisibilityChanged(View changedView, int vis) {
+        super.onVisibilityChanged(changedView, vis);
+        updateAnimating();
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
new file mode 100644
index 0000000..fabae57
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ */
+
+package com.android.settingslib.wifi;
+
+import android.content.Intent;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+
+import java.util.List;
+
+public class WifiStatusTracker {
+
+    private final WifiManager mWifiManager;
+    public boolean enabled;
+    public boolean connected;
+    public String ssid;
+    public int rssi;
+    public int level;
+
+    public WifiStatusTracker(WifiManager wifiManager) {
+        mWifiManager = wifiManager;
+    }
+
+    public void handleBroadcast(Intent intent) {
+        String action = intent.getAction();
+        if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+            enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
+        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+            final NetworkInfo networkInfo = (NetworkInfo)
+                    intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+            connected = networkInfo != null && networkInfo.isConnected();
+            // If Connected grab the signal strength and ssid.
+            if (connected) {
+                // try getting it out of the intent first
+                WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
+                        ? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
+                        : mWifiManager.getConnectionInfo();
+                if (info != null) {
+                    ssid = getSsid(info);
+                } else {
+                    ssid = null;
+                }
+            } else if (!connected) {
+                ssid = null;
+            }
+        } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+            // Default to -200 as its below WifiManager.MIN_RSSI.
+            rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
+            level = WifiManager.calculateSignalLevel(rssi, 5);
+        }
+    }
+
+    private String getSsid(WifiInfo info) {
+        String ssid = info.getSSID();
+        if (ssid != null) {
+            return ssid;
+        }
+        // OK, it's not in the connectionInfo; we have to go hunting for it
+        List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
+        int length = networks.size();
+        for (int i = 0; i < length; i++) {
+            if (networks.get(i).networkId == info.getNetworkId()) {
+                return networks.get(i).SSID;
+            }
+        }
+        return null;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index e2d2ffb..a0bbbe3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -23,16 +23,14 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.net.MobileDataController;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.QSTileBaseView;
 import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataController;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataController.DataUsageInfo;
 import com.android.systemui.statusbar.policy.SignalCallbackAdapter;
 
 /** Quick settings tile: Cellular **/
@@ -247,7 +245,7 @@
             final DataUsageDetailView v = (DataUsageDetailView) (convertView != null
                     ? convertView
                     : LayoutInflater.from(mContext).inflate(R.layout.data_usage, parent, false));
-            final DataUsageInfo info = mDataController.getDataUsageInfo();
+            final MobileDataController.DataUsageInfo info = mDataController.getDataUsageInfo();
             if (info == null) return v;
             v.bind(info);
             return v;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
index d0ae383..d814b1c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
@@ -23,11 +23,10 @@
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-
+import com.android.settingslib.net.MobileDataController;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.DataUsageGraph;
-import com.android.systemui.statusbar.policy.NetworkController;
 
 import java.text.DecimalFormat;
 
@@ -60,7 +59,7 @@
                 R.dimen.qs_data_usage_text_size);
     }
 
-    public void bind(NetworkController.MobileDataController.DataUsageInfo info) {
+    public void bind(MobileDataController.DataUsageInfo info) {
         final Resources res = mContext.getResources();
         final int titleId;
         final long bytes;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index b4bb392..4e24d54 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -421,6 +421,8 @@
         if (state.startHidden) {
             state.startHidden = false;
             mRecentsView.setStackViewVisibility(View.INVISIBLE);
+        } else {
+            mRecentsView.setStackViewVisibility(View.VISIBLE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 9e3cf37..e6a291c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -594,7 +594,9 @@
 
         // Setup the animation with the screenshot just taken
         if (mScreenshotAnimation != null) {
-            mScreenshotAnimation.end();
+            if (mScreenshotAnimation.isStarted()) {
+                mScreenshotAnimation.end();
+            }
             mScreenshotAnimation.removeAllListeners();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 4328e24..83dbde5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -105,36 +105,29 @@
         }
 
         public boolean cacheContentViews(Context ctx, Notification updatedNotification) {
-            boolean cached = false;
+            boolean applyInPlace = false;
             if (updatedNotification != null) {
                 final Notification.Builder updatedNotificationBuilder
                         = Notification.Builder.recoverBuilder(ctx, updatedNotification);
                 final RemoteViews newContentView = updatedNotificationBuilder.makeContentView();
-                if (!compareRemoteViews(cachedContentView, newContentView)) {
-                    cachedContentView = newContentView;
-                    cached |= true;
-                }
                 final RemoteViews newBigContentView =
                         updatedNotificationBuilder.makeBigContentView();
-                if (!compareRemoteViews(cachedBigContentView, newBigContentView)) {
-                    cachedBigContentView = newBigContentView;
-                    cached |= true;
-                }
                 final RemoteViews newHeadsUpContentView =
                         updatedNotificationBuilder.makeHeadsUpContentView();
-                if (!compareRemoteViews(cachedHeadsUpContentView, newBigContentView)) {
-                    cachedHeadsUpContentView = newHeadsUpContentView;
-                    cached |= true;
-                }
                 final Notification updatedPublicNotification = updatedNotification.publicVersion;
                 final RemoteViews newPubContentView = (updatedPublicNotification != null)
                         ? Notification.Builder.recoverBuilder(
                                 ctx, updatedPublicNotification).makeContentView()
                         : null;
-                if (!compareRemoteViews(cachedPublicContentView, newPubContentView)) {
-                    cachedPublicContentView = newPubContentView;
-                    cached |= true;
-                }
+
+                applyInPlace = compareRemoteViews(cachedContentView, newContentView)
+                        && compareRemoteViews(cachedBigContentView, newBigContentView)
+                        && compareRemoteViews(cachedHeadsUpContentView, newHeadsUpContentView)
+                        && compareRemoteViews(cachedPublicContentView, newPubContentView);
+                cachedPublicContentView = newPubContentView;
+                cachedHeadsUpContentView = newHeadsUpContentView;
+                cachedBigContentView = newBigContentView;
+                cachedContentView = newContentView;
             } else {
                 final Notification.Builder builder
                         = Notification.Builder.recoverBuilder(ctx, notification.getNotification());
@@ -150,9 +143,9 @@
                             = Notification.Builder.recoverBuilder(ctx, publicNotification);
                     cachedPublicContentView = publicBuilder.makeContentView();
                 }
-                cached = true;
+                applyInPlace = false;
             }
-            return cached;
+            return applyInPlace;
         }
 
         // Returns true if the RemoteViews are the same.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 38656ee..f8c72b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.telephony.SubscriptionInfo;
-
+import com.android.settingslib.net.MobileDataController;
 import com.android.settingslib.wifi.AccessPoint;
 
 import java.util.List;
@@ -85,22 +85,4 @@
             void onSettingsActivityTriggered(Intent settingsIntent);
         }
     }
-
-    /**
-     * Tracks mobile data support and usage.
-     */
-    public interface MobileDataController {
-        boolean isMobileDataSupported();
-        boolean isMobileDataEnabled();
-        void setMobileDataEnabled(boolean enabled);
-        DataUsageInfo getDataUsageInfo();
-
-        public static class DataUsageInfo {
-            public String carrier;
-            public String period;
-            public long limitLevel;
-            public long warningLevel;
-            public long usageLevel;
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 2996808..909f497 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.policy;
 
-import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -39,10 +37,10 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.MathUtils;
-
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.settingslib.net.MobileDataController;
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
 
@@ -57,9 +55,11 @@
 import java.util.Locale;
 import java.util.Map;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+
 /** Platform implementation of the network controller. **/
 public class NetworkControllerImpl extends BroadcastReceiver
-        implements NetworkController, DemoMode {
+        implements NetworkController, DemoMode, MobileDataController.NetworkNameProvider {
     // debug
     static final String TAG = "NetworkController";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -94,7 +94,7 @@
     // SIM for most actions.  This may be null if there aren't any SIMs around.
     private MobileSignalController mDefaultSignalController;
     private final AccessPointControllerImpl mAccessPoints;
-    private final MobileDataControllerImpl mMobileDataController;
+    private final MobileDataController mMobileDataController;
 
     private boolean mInetCondition; // Used for Logging and demo.
 
@@ -139,7 +139,7 @@
                 SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
                 new CallbackHandler(),
                 new AccessPointControllerImpl(context, bgLooper),
-                new MobileDataControllerImpl(context),
+                new MobileDataController(context),
                 new SubscriptionDefaults());
         mReceiverHandler.post(mRegisterListeners);
     }
@@ -150,7 +150,7 @@
             SubscriptionManager subManager, Config config, Looper bgLooper,
             CallbackHandler callbackHandler,
             AccessPointControllerImpl accessPointController,
-            MobileDataControllerImpl mobileDataController,
+            MobileDataController mobileDataController,
             SubscriptionDefaults defaultsHandler) {
         mContext = context;
         mConfig = config;
@@ -174,7 +174,7 @@
         mMobileDataController = mobileDataController;
         mMobileDataController.setNetworkController(this);
         // TODO: Find a way to move this into MobileDataController.
-        mMobileDataController.setCallback(new MobileDataControllerImpl.Callback() {
+        mMobileDataController.setCallback(new MobileDataController.Callback() {
             @Override
             public void onMobileDataEnabled(boolean enabled) {
                 mCallbackHandler.setMobileDataEnabled(enabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 9b1e72a..eab6e13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -18,20 +18,16 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
 import android.util.Log;
-
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.AsyncChannel;
+import com.android.settingslib.wifi.WifiStatusTracker;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 
-import java.util.List;
 import java.util.Objects;
 
 
@@ -40,12 +36,14 @@
     private final WifiManager mWifiManager;
     private final AsyncChannel mWifiChannel;
     private final boolean mHasMobileData;
+    private final WifiStatusTracker mWifiTracker;
 
     public WifiSignalController(Context context, boolean hasMobileData,
             CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
         super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
                 callbackHandler, networkController);
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mWifiTracker = new WifiStatusTracker(mWifiManager);
         mHasMobileData = hasMobileData;
         Handler handler = new WifiHandler();
         mWifiChannel = new AsyncChannel();
@@ -93,54 +91,15 @@
      * Extract wifi state directly from broadcasts about changes in wifi state.
      */
     public void handleBroadcast(Intent intent) {
-        String action = intent.getAction();
-        if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-            mCurrentState.enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-            final NetworkInfo networkInfo = (NetworkInfo)
-                    intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-            mCurrentState.connected = networkInfo != null && networkInfo.isConnected();
-            // If Connected grab the signal strength and ssid.
-            if (mCurrentState.connected) {
-                // try getting it out of the intent first
-                WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
-                        ? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
-                        : mWifiManager.getConnectionInfo();
-                if (info != null) {
-                    mCurrentState.ssid = getSsid(info);
-                } else {
-                    mCurrentState.ssid = null;
-                }
-            } else if (!mCurrentState.connected) {
-                mCurrentState.ssid = null;
-            }
-        } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-            // Default to -200 as its below WifiManager.MIN_RSSI.
-            mCurrentState.rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
-            mCurrentState.level = WifiManager.calculateSignalLevel(
-                    mCurrentState.rssi, WifiIcons.WIFI_LEVEL_COUNT);
-        }
-
+        mWifiTracker.handleBroadcast(intent);
+        mCurrentState.enabled = mWifiTracker.enabled;
+        mCurrentState.connected = mWifiTracker.connected;
+        mCurrentState.ssid = mWifiTracker.ssid;
+        mCurrentState.rssi = mWifiTracker.rssi;
+        mCurrentState.level = mWifiTracker.level;
         notifyListenersIfNecessary();
     }
 
-    private String getSsid(WifiInfo info) {
-        String ssid = info.getSSID();
-        if (ssid != null) {
-            return ssid;
-        }
-        // OK, it's not in the connectionInfo; we have to go hunting for it
-        List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
-        int length = networks.size();
-        for (int i = 0; i < length; i++) {
-            if (networks.get(i).networkId == info.getNetworkId()) {
-                return networks.get(i).SSID;
-            }
-        }
-        return null;
-    }
-
     @VisibleForTesting
     void setActivity(int wifiActivity) {
         mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 30c08cd..13fc47d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -33,6 +33,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.cdma.EriInfo;
+import com.android.settingslib.net.MobileDataController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
@@ -95,7 +96,7 @@
         mCallbackHandler = mock(CallbackHandler.class);
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class),
+                mock(AccessPointControllerImpl.class), mock(MobileDataController.class),
                 mMockSubDefaults);
         setupNetworkController();
 
@@ -136,7 +137,7 @@
               = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                         mConfig, Looper.getMainLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
-                        mock(MobileDataControllerImpl.class), mMockSubDefaults);
+                        mock(MobileDataController.class), mMockSubDefaults);
 
       setupNetworkController();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 0ec8802..587e2b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -4,6 +4,7 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.settingslib.net.MobileDataController;
 import org.mockito.Mockito;
 
 @SmallTest
@@ -87,7 +88,7 @@
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 Mockito.mock(AccessPointControllerImpl.class),
-                Mockito.mock(MobileDataControllerImpl.class), mMockSubDefaults);
+                Mockito.mock(MobileDataController.class), mMockSubDefaults);
         setupNetworkController();
 
         setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 660fd9c..760aa9a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -29,6 +29,7 @@
 
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.settingslib.net.MobileDataController;
 import com.android.systemui.R;
 
 import org.mockito.ArgumentCaptor;
@@ -46,7 +47,7 @@
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class),
+                mock(AccessPointControllerImpl.class), mock(MobileDataController.class),
                 mMockSubDefaults);
         setupNetworkController();
 
@@ -95,7 +96,7 @@
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class),
+                mock(AccessPointControllerImpl.class), mock(MobileDataController.class),
                 mMockSubDefaults);
         setupNetworkController();
 
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index ab1d775..ae9ddc0 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -30,6 +30,7 @@
 import com.android.internal.view.IInputMethodSession;
 import com.android.internal.view.IInputSessionCallback;
 import com.android.internal.view.InputBindResult;
+import com.android.internal.view.InputMethodClient;
 import com.android.server.statusbar.StatusBarManagerService;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -160,8 +161,8 @@
     static final int MSG_START_INPUT = 2000;
     static final int MSG_RESTART_INPUT = 2010;
 
-    static final int MSG_UNBIND_METHOD = 3000;
-    static final int MSG_BIND_METHOD = 3010;
+    static final int MSG_UNBIND_CLIENT = 3000;
+    static final int MSG_BIND_CLIENT = 3010;
     static final int MSG_SET_ACTIVE = 3020;
     static final int MSG_SET_INTERACTIVE = 3030;
     static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 3040;
@@ -935,7 +936,7 @@
                 || (newLocale != null && !newLocale.equals(mLastSystemLocale))) {
             if (!updateOnlyWhenLocaleChanged) {
                 hideCurrentInputLocked(0, null);
-                unbindCurrentMethodLocked(true, false);
+                resetCurrentMethodAndClient(InputMethodClient.UNBIND_REASON_RESET_IME);
             }
             if (DEBUG) {
                 Slog.i(TAG, "Locale has been changed to " + newLocale);
@@ -1208,7 +1209,8 @@
          }
     }
 
-    void unbindCurrentClientLocked() {
+    void unbindCurrentClientLocked(
+            /* @InputMethodClient.UnbindReason */ final int unbindClientReason) {
         if (mCurClient != null) {
             if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client = "
                     + mCurClient.client.asBinder());
@@ -1222,8 +1224,8 @@
 
             executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
                     MSG_SET_ACTIVE, 0, mCurClient));
-            executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
-                    MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
+            executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
+                    MSG_UNBIND_CLIENT, mCurSeq, unbindClientReason, mCurClient.client));
             mCurClient.sessionRequested = false;
             mCurClient = null;
 
@@ -1324,7 +1326,7 @@
             mCurClientInKeyguard = isKeyguardLocked();
             // If the client is changing, we need to switch over to the new
             // one.
-            unbindCurrentClientLocked();
+            unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_SWITCH_CLIENT);
             if (DEBUG) Slog.v(TAG, "switching to client: client = "
                     + cs.client.asBinder() + " keyguard=" + mCurClientInKeyguard);
 
@@ -1395,7 +1397,7 @@
             throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
         }
 
-        unbindCurrentMethodLocked(false, true);
+        unbindCurrentMethodLocked(true);
 
         mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE);
         mCurIntent.setComponent(info.getComponent());
@@ -1453,7 +1455,7 @@
                 mCurMethod = IInputMethod.Stub.asInterface(service);
                 if (mCurToken == null) {
                     Slog.w(TAG, "Service connected without a token!");
-                    unbindCurrentMethodLocked(false, false);
+                    unbindCurrentMethodLocked(false);
                     return;
                 }
                 if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
@@ -1479,7 +1481,7 @@
                     InputBindResult res = attachNewInputLocked(true);
                     if (res.method != null) {
                         executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
-                                MSG_BIND_METHOD, mCurClient.client, res));
+                                MSG_BIND_CLIENT, mCurClient.client, res));
                     }
                     return;
                 }
@@ -1490,11 +1492,7 @@
         channel.dispose();
     }
 
-    void unbindCurrentMethodLocked(boolean resetCurrentMethodAndClient, boolean savePosition) {
-        if (resetCurrentMethodAndClient) {
-            mCurMethodId = null;
-        }
-
+    void unbindCurrentMethodLocked(boolean savePosition) {
         if (mVisibleBound) {
             mContext.unbindService(mVisibleConnection);
             mVisibleBound = false;
@@ -1520,10 +1518,13 @@
 
         mCurId = null;
         clearCurMethodLocked();
+    }
 
-        if (resetCurrentMethodAndClient) {
-            unbindCurrentClientLocked();
-        }
+    void resetCurrentMethodAndClient(
+            /* @InputMethodClient.UnbindReason */ final int unbindClientReason) {
+        mCurMethodId = null;
+        unbindCurrentMethodLocked(false);
+        unbindCurrentClientLocked(unbindClientReason);
     }
 
     void requestClientSessionLocked(ClientState cs) {
@@ -1590,8 +1591,9 @@
                 mShowRequested = mInputShown;
                 mInputShown = false;
                 if (mCurClient != null) {
-                    executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
-                            MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
+                    executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
+                            MSG_UNBIND_CLIENT, InputMethodClient.UNBIND_REASON_DISCONNECT_IME,
+                            mCurSeq, mCurClient.client));
                 }
             }
         }
@@ -1876,12 +1878,12 @@
                 setInputMethodLocked(id, mSettings.getSelectedInputMethodSubtypeId(id));
             } catch (IllegalArgumentException e) {
                 Slog.w(TAG, "Unknown input method from prefs: " + id, e);
-                unbindCurrentMethodLocked(true, false);
+                resetCurrentMethodAndClient(InputMethodClient.UNBIND_REASON_SWITCH_IME_FAILED);
             }
             mShortcutInputMethodsAndSubtypes.clear();
         } else {
             // There is no longer an input method set, so stop any current one.
-            unbindCurrentMethodLocked(true, false);
+            resetCurrentMethodAndClient(InputMethodClient.UNBIND_REASON_NO_IME);
         }
         // Here is not the perfect place to reset the switching controller. Ideally
         // mSwitchingController and mSettings should be able to share the same state.
@@ -1967,7 +1969,7 @@
                 intent.putExtra("input_method_id", id);
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
             }
-            unbindCurrentClientLocked();
+            unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_SWITCH_IME);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -2771,14 +2773,14 @@
 
             // ---------------------------------------------------------
 
-            case MSG_UNBIND_METHOD:
+            case MSG_UNBIND_CLIENT:
                 try {
-                    ((IInputMethodClient)msg.obj).onUnbindMethod(msg.arg1);
+                    ((IInputMethodClient)msg.obj).onUnbindMethod(msg.arg1, msg.arg2);
                 } catch (RemoteException e) {
                     // There is nothing interesting about the last client dying.
                 }
                 return true;
-            case MSG_BIND_METHOD: {
+            case MSG_BIND_CLIENT: {
                 args = (SomeArgs)msg.obj;
                 IInputMethodClient client = (IInputMethodClient)args.arg1;
                 InputBindResult res = (InputBindResult)args.arg2;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index c228422..9eb66dd 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -88,6 +88,7 @@
     private SettingsObserver mSettingObserver;
 
     native static boolean vibratorExists();
+    native static void vibratorInit();
     native static void vibratorOn(long milliseconds);
     native static void vibratorOff();
 
@@ -195,6 +196,7 @@
     }
 
     VibratorService(Context context) {
+        vibratorInit();
         // Reset the hardware to a default state, in case this is a runtime
         // restart instead of a fresh boot.
         vibratorOff();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 025126f..6e6bfb7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17969,7 +17969,7 @@
 
         app.systemNoUi = false;
 
-        final int PROCESS_STATE_TOP = mTopProcessState;
+        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
 
         // Determine the importance of the process, starting with most
         // important to least, and assign an appropriate OOM adjustment.
@@ -17984,7 +17984,7 @@
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "top-activity";
             foregroundActivities = true;
-            procState = PROCESS_STATE_TOP;
+            procState = PROCESS_STATE_CUR_TOP;
         } else if (app.instrumentationClass != null) {
             // Don't want to kill running instrumentation.
             adj = ProcessList.FOREGROUND_APP_ADJ;
@@ -18038,8 +18038,8 @@
                         adj = ProcessList.VISIBLE_APP_ADJ;
                         app.adjType = "visible";
                     }
-                    if (procState > PROCESS_STATE_TOP) {
-                        procState = PROCESS_STATE_TOP;
+                    if (procState > PROCESS_STATE_CUR_TOP) {
+                        procState = PROCESS_STATE_CUR_TOP;
                     }
                     schedGroup = Process.THREAD_GROUP_DEFAULT;
                     app.cached = false;
@@ -18057,8 +18057,8 @@
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "pausing";
                     }
-                    if (procState > PROCESS_STATE_TOP) {
-                        procState = PROCESS_STATE_TOP;
+                    if (procState > PROCESS_STATE_CUR_TOP) {
+                        procState = PROCESS_STATE_CUR_TOP;
                     }
                     schedGroup = Process.THREAD_GROUP_DEFAULT;
                     app.cached = false;
@@ -18096,7 +18096,8 @@
             }
         }
 
-        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
+                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
             if (app.foregroundServices) {
                 // The user is aware of this app, so make it visible.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index e4dbf65..8fac9da 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -871,7 +871,7 @@
             return false;
         }
         PackageSetting sysPkg = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
-        if (sysPkg != null) {
+        if (sysPkg != null && sysPkg.pkg != null) {
             if ((sysPkg.pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
                 return false;
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a9bd71f..3ad2610 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3704,6 +3704,10 @@
         // This is used by freeform <-> recents windows transition. We need to synchronize
         // the animation with the appearance of the content of recents, so we will make
         // animation stay on the first or last frame a little longer.
+        if (specs == null) {
+            Slog.wtf(TAG, "prolongAnimationsFromSpecs: AppTransitionAnimationSpec is null!");
+            return;
+        }
         mTmpTaskIds.clear();
         for (int i = specs.length - 1; i >= 0; i--) {
             mTmpTaskIds.put(specs[i].taskId, 0);
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 64278ed..03fbd19 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -22,32 +22,69 @@
 
 #include <utils/misc.h>
 #include <utils/Log.h>
-#include <hardware_legacy/vibrator.h>
+#include <hardware/vibrator.h>
 
 #include <stdio.h>
 
 namespace android
 {
 
+static hw_module_t *gVibraModule = NULL;
+static vibrator_device_t *gVibraDevice = NULL;
+
+static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
+{
+    if (gVibraModule != NULL) {
+        return;
+    }
+
+    int err = hw_get_module(VIBRATOR_HARDWARE_MODULE_ID, (hw_module_t const**)&gVibraModule);
+
+    if (err) {
+        ALOGE("Couldn't load %s module (%s)", VIBRATOR_HARDWARE_MODULE_ID, strerror(-err));
+    } else {
+        if (gVibraModule) {
+            vibrator_open(gVibraModule, &gVibraDevice);
+        }
+    }
+}
+
 static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
 {
-    return vibrator_exists() > 0 ? JNI_TRUE : JNI_FALSE;
+    if (gVibraModule && gVibraDevice) {
+        return JNI_TRUE;
+    } else {
+        return JNI_FALSE;
+    }
 }
 
 static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
 {
-    // ALOGI("vibratorOn\n");
-    vibrator_on(timeout_ms);
+    if (gVibraDevice) {
+        int err = gVibraDevice->vibrator_on(gVibraDevice, timeout_ms);
+        if (err != 0) {
+            ALOGE("The hw module failed in vibrator_on: %s", strerror(-err));
+        }
+    } else {
+        ALOGW("Tried to vibrate but there is no vibrator device.");
+    }
 }
 
 static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
 {
-    // ALOGI("vibratorOff\n");
-    vibrator_off();
+    if (gVibraDevice) {
+        int err = gVibraDevice->vibrator_off(gVibraDevice);
+        if (err != 0) {
+            ALOGE("The hw module failed in vibrator_off(): %s", strerror(-err));
+        }
+    } else {
+        ALOGW("Tried to stop vibrating but there is no vibrator device.");
+    }
 }
 
 static const JNINativeMethod method_table[] = {
     { "vibratorExists", "()Z", (void*)vibratorExists },
+    { "vibratorInit", "()V", (void*)vibratorInit },
     { "vibratorOn", "(J)V", (void*)vibratorOn },
     { "vibratorOff", "()V", (void*)vibratorOff }
 };
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index be190cb..b5654ee 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -152,18 +152,23 @@
             getInputWindowHandleObjLocalRef(env);
 }
 
-static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
-        SpriteIcon* outSpriteIcon) {
-    PointerIcon pointerIcon;
+static void loadSystemIconAsSpriteWithPointerIcon(JNIEnv* env, jobject contextObj, int32_t style,
+        PointerIcon* outPointerIcon, SpriteIcon* outSpriteIcon) {
     status_t status = android_view_PointerIcon_loadSystemIcon(env,
-            contextObj, style, &pointerIcon);
+            contextObj, style, outPointerIcon);
     if (!status) {
-        pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
-        outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
-        outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
+        outPointerIcon->bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
+        outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
+        outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
     }
 }
 
+static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
+                                   SpriteIcon* outSpriteIcon) {
+    PointerIcon pointerIcon;
+    loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
+}
+
 enum {
     WM_ACTION_PASS_TO_USER = 1,
 };
@@ -238,7 +243,8 @@
     /* --- PointerControllerPolicyInterface implementation --- */
 
     virtual void loadPointerResources(PointerResources* outResources);
-    virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources);
+    virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
+            std::map<int32_t, PointerAnimation>* outAnimationResources);
     virtual int32_t getDefaultPointerIconId();
 
 private:
@@ -1041,14 +1047,31 @@
             &outResources->spotAnchor);
 }
 
-void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources) {
+void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
+        std::map<int32_t, PointerAnimation>* outAnimationResources) {
     JNIEnv* env = jniEnv();
 
     for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING;
              ++iconId) {
-        loadSystemIconAsSprite(env, mContextObj, iconId, &((*outResources)[iconId]));
+        PointerIcon pointerIcon;
+        loadSystemIconAsSpriteWithPointerIcon(
+                env, mContextObj, iconId, &pointerIcon, &((*outResources)[iconId]));
+        if (!pointerIcon.bitmapFrames.empty()) {
+            PointerAnimation& animationData = (*outAnimationResources)[iconId];
+            size_t numFrames = pointerIcon.bitmapFrames.size() + 1;
+            animationData.durationPerFrame =
+                    milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
+            animationData.animationFrames.reserve(numFrames);
+            animationData.animationFrames.push_back(SpriteIcon(
+                    pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY));
+            for (size_t i = 0; i < numFrames - 1; ++i) {
+              animationData.animationFrames.push_back(SpriteIcon(
+                      pointerIcon.bitmapFrames[i], pointerIcon.hotSpotX, pointerIcon.hotSpotY));
+            }
+        }
     }
-    loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL, &((*outResources)[POINTER_ICON_STYLE_NULL]));
+    loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL,
+            &((*outResources)[POINTER_ICON_STYLE_NULL]));
 }
 
 int32_t NativeInputManager::getDefaultPointerIconId() {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index f396c2d..8fee91f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -362,7 +362,6 @@
                             }
                         } catch (PackageManager.NameNotFoundException e) {
                             Slog.w(TAG, "Failure looking up interaction service " + comp);
-                        } catch (RemoteException e) {
                         }
                     }
                 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 30296e1..109d214 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -116,7 +116,7 @@
         VoiceInteractionServiceInfo info;
         try {
             info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
-        } catch (RemoteException|PackageManager.NameNotFoundException e) {
+        } catch (PackageManager.NameNotFoundException e) {
             Slog.w(TAG, "Voice interaction service not found: " + service, e);
             mInfo = null;
             mSessionComponentName = null;
diff --git a/tests/RenderScriptTests/Fountain/Android.mk b/tests/RenderScriptTests/Fountain/Android.mk
deleted file mode 100644
index 0517aef..0000000
--- a/tests/RenderScriptTests/Fountain/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-
-LOCAL_SDK_VERSION := 17
-
-LOCAL_PACKAGE_NAME := RsFountain
-
-include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/Fountain/AndroidManifest.xml b/tests/RenderScriptTests/Fountain/AndroidManifest.xml
deleted file mode 100644
index d19b8c3..0000000
--- a/tests/RenderScriptTests/Fountain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.rs.fountain">
-    <uses-sdk android:minSdkVersion="14" />
-    <application
-        android:label="RsFountain"
-        android:hardwareAccelerated="true"
-        android:icon="@drawable/test_pattern">
-        <activity android:name="Fountain">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RenderScriptTests/Fountain/_index.html b/tests/RenderScriptTests/Fountain/_index.html
deleted file mode 100644
index 223242f..0000000
--- a/tests/RenderScriptTests/Fountain/_index.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<p>An example that renders many dots on the screen that follow a user's touch. The dots fall 
-to the bottom of the screen when the user releases the finger.</p>
-
-
-
diff --git a/tests/RenderScriptTests/Fountain/res/drawable/test_pattern.png b/tests/RenderScriptTests/Fountain/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/tests/RenderScriptTests/Fountain/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/Fountain.java b/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/Fountain.java
deleted file mode 100644
index 311455a..0000000
--- a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/Fountain.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.rs.fountain;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class Fountain extends Activity {
-    //EventListener mListener = new EventListener();
-
-    private static final String LOG_TAG = "libRS_jni";
-    private static final boolean DEBUG  = false;
-    private static final boolean LOG_ENABLED = false;
-
-    private FountainView mView;
-
-    // get the current looper (from your Activity UI thread for instance
-
-
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new FountainView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        Log.e("rs", "onResume");
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        Log.e("rs", "onPause");
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onPause();
-        mView.pause();
-
-
-
-        //Runtime.getRuntime().exit(0);
-    }
-
-
-    static void log(String message) {
-        if (LOG_ENABLED) {
-            Log.v(LOG_TAG, message);
-        }
-    }
-
-
-}
-
diff --git a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainRS.java b/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainRS.java
deleted file mode 100644
index 646c807..0000000
--- a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainRS.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.rs.fountain;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-
-public class FountainRS {
-    public static final int PART_COUNT = 50000;
-
-    public FountainRS() {
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private ScriptC_fountain mScript;
-    public void init(RenderScriptGL rs, Resources res) {
-        mRS = rs;
-        mRes = res;
-
-        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setVaryingColor(true);
-        rs.bindProgramFragment(pfb.create());
-
-        ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);//
- //                                                        Allocation.USAGE_GRAPHICS_VERTEX);
-
-        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
-        smb.addVertexAllocation(points.getAllocation());
-        smb.addIndexSetType(Mesh.Primitive.POINT);
-        Mesh sm = smb.create();
-
-        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
-        mScript.set_partMesh(sm);
-        mScript.bind_point(points);
-        mRS.bindRootScript(mScript);
-    }
-
-    boolean holdingColor[] = new boolean[10];
-    public void newTouchPosition(float x, float y, float pressure, int id) {
-        if (id >= holdingColor.length) {
-            return;
-        }
-        int rate = (int)(pressure * pressure * 500.f);
-        if (rate > 500) {
-            rate = 500;
-        }
-        if (rate > 0) {
-            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
-            holdingColor[id] = true;
-        } else {
-            holdingColor[id] = false;
-        }
-
-    }
-}
diff --git a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java b/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java
deleted file mode 100644
index 98cec55..0000000
--- a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.rs.fountain;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class FountainView extends RSSurfaceView {
-
-    public FountainView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private FountainRS mRender;
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new FountainRS();
-            mRender.init(mRS, getResources());
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        int act = ev.getActionMasked();
-        if (act == ev.ACTION_UP) {
-            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
-            return false;
-        } else if (act == MotionEvent.ACTION_POINTER_UP) {
-            // only one pointer going up, we can get the index like this
-            int pointerIndex = ev.getActionIndex();
-            int pointerId = ev.getPointerId(pointerIndex);
-            mRender.newTouchPosition(0, 0, 0, pointerId);
-        }
-        int count = ev.getHistorySize();
-        int pcount = ev.getPointerCount();
-
-        for (int p=0; p < pcount; p++) {
-            int id = ev.getPointerId(p);
-            mRender.newTouchPosition(ev.getX(p),
-                                     ev.getY(p),
-                                     ev.getPressure(p),
-                                     id);
-
-            for (int i=0; i < count; i++) {
-                mRender.newTouchPosition(ev.getHistoricalX(p, i),
-                                         ev.getHistoricalY(p, i),
-                                         ev.getHistoricalPressure(p, i),
-                                         id);
-            }
-        }
-        return true;
-    }
-}
-
-
diff --git a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/fountain.rs b/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/fountain.rs
deleted file mode 100644
index 151b689..0000000
--- a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/fountain.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Fountain test script
-#pragma version(1)
-#pragma rs_fp_relaxed
-
-#pragma rs java_package_name(com.example.android.rs.fountain)
-
-#pragma stateFragment(parent)
-
-#include "rs_graphics.rsh"
-
-static int newPart = 0;
-rs_mesh partMesh;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
-    float2 delta;
-    float2 position;
-    uchar4 color;
-} Point_t;
-Point_t *point;
-
-int root() {
-    float dt = min(rsGetDt(), 0.1f);
-    rsgClearColor(0.f, 0.f, 0.f, 1.f);
-    const float height = rsgGetHeight();
-    const int size = rsAllocationGetDimX(rsGetAllocation(point));
-    float dy2 = dt * (10.f);
-    Point_t * p = point;
-    for (int ct=0; ct < size; ct++) {
-        p->delta.y += dy2;
-        p->position += p->delta;
-        if ((p->position.y > height) && (p->delta.y > 0)) {
-            p->delta.y *= -0.3f;
-        }
-        p++;
-    }
-
-    rsgDrawMesh(partMesh);
-    return 1;
-}
-
-static float4 partColor[10];
-void addParticles(int rate, float x, float y, int index, bool newColor)
-{
-    if (newColor) {
-        partColor[index].x = rsRand(0.5f, 1.0f);
-        partColor[index].y = rsRand(1.0f);
-        partColor[index].z = rsRand(1.0f);
-    }
-    float rMax = ((float)rate) * 0.02f;
-    int size = rsAllocationGetDimX(rsGetAllocation(point));
-    uchar4 c = rsPackColorTo8888(partColor[index]);
-
-    Point_t * np = &point[newPart];
-    float2 p = {x, y};
-    while (rate--) {
-        float angle = rsRand(3.14f * 2.f);
-        float len = rsRand(rMax);
-        np->delta.x = len * sin(angle);
-        np->delta.y = len * cos(angle);
-        np->position = p;
-        np->color = c;
-        newPart++;
-        np++;
-        if (newPart >= size) {
-            newPart = 0;
-            np = &point[newPart];
-        }
-    }
-}
-
diff --git a/tests/RenderScriptTests/FountainFbo/Android.mk b/tests/RenderScriptTests/FountainFbo/Android.mk
deleted file mode 100644
index c0f3323..0000000
--- a/tests/RenderScriptTests/FountainFbo/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-
-# TODO: build fails with this set
-# LOCAL_SDK_VERSION := current
-
-LOCAL_PACKAGE_NAME := RsFountainFbo
-LOCAL_SDK_VERSION := 14
-
-include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/FountainFbo/AndroidManifest.xml b/tests/RenderScriptTests/FountainFbo/AndroidManifest.xml
deleted file mode 100644
index 082744b..0000000
--- a/tests/RenderScriptTests/FountainFbo/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.rs.fountainfbo">
-    <uses-sdk android:minSdkVersion="14" />
-    <application
-        android:label="RsFountainFbo"
-        android:hardwareAccelerated="true"
-        android:icon="@drawable/test_pattern">
-        <activity android:name="FountainFbo">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RenderScriptTests/FountainFbo/_index.html b/tests/RenderScriptTests/FountainFbo/_index.html
deleted file mode 100644
index 5508657..0000000
--- a/tests/RenderScriptTests/FountainFbo/_index.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<p>An example that renders many dots on the screen that follow a user's touch. The dots fall 
-to the bottom of the screen when no touch is detected. This example modifies
-the <a href="../Fountain/index.html">Fountain</a> sample to include rendering to a
-a framebuffer object as well as the default framebuffer.</p>
-
-
-
diff --git a/tests/RenderScriptTests/FountainFbo/res/drawable/test_pattern.png b/tests/RenderScriptTests/FountainFbo/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/tests/RenderScriptTests/FountainFbo/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFbo.java b/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFbo.java
deleted file mode 100644
index d8ba30fd..0000000
--- a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFbo.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.rs.fountainfbo;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-
-public class FountainFbo extends Activity {
-    private static final String LOG_TAG = "libRS_jni";
-    private static final boolean DEBUG  = false;
-    private static final boolean LOG_ENABLED = false;
-
-    private FountainFboView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        /* Create our Preview view and set it as the content of our Activity */
-        mView = new FountainFboView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        Log.e("rs", "onResume");
-
-        /* Ideally a game should implement onResume() and onPause()
-         to take appropriate action when the activity loses focus */
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        Log.e("rs", "onPause");
-
-        /* Ideally a game should implement onResume() and onPause()
-        to take appropriate action when the activity loses focus */
-        super.onPause();
-        mView.pause();
-    }
-
-    static void log(String message) {
-        if (LOG_ENABLED) {
-            Log.v(LOG_TAG, message);
-        }
-    }
-}
-
diff --git a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboRS.java b/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboRS.java
deleted file mode 100644
index 3bf3ff1..0000000
--- a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboRS.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.rs.fountainfbo;
-
-import android.content.res.Resources;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.Mesh;
-import android.renderscript.ProgramFragment;
-import android.renderscript.ProgramFragmentFixedFunction;
-import android.renderscript.RenderScriptGL;
-import android.renderscript.Type;
-
-public class FountainFboRS {
-    public static final int PART_COUNT = 50000;
-
-    public FountainFboRS() {
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private ScriptC_fountainfbo mScript;
-    private Allocation mColorBuffer;
-    private ProgramFragment mProgramFragment;
-    private ProgramFragment mTextureProgramFragment;
-    public void init(RenderScriptGL rs, Resources res) {
-      mRS = rs;
-      mRes = res;
-
-      ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
-
-      Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
-      smb.addVertexAllocation(points.getAllocation());
-      smb.addIndexSetType(Mesh.Primitive.POINT);
-      Mesh sm = smb.create();
-
-      mScript = new ScriptC_fountainfbo(mRS, mRes, R.raw.fountainfbo);
-      mScript.set_partMesh(sm);
-      mScript.bind_point(points);
-
-      ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
-      pfb.setVaryingColor(true);
-      mProgramFragment = pfb.create();
-      mScript.set_gProgramFragment(mProgramFragment);
-
-      /* Second fragment shader to use a texture (framebuffer object) to draw with */
-      pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-          ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-
-      /* Set the fragment shader in the Renderscript runtime */
-      mTextureProgramFragment = pfb.create();
-      mScript.set_gTextureProgramFragment(mTextureProgramFragment);
-
-      /* Create the allocation for the color buffer */
-      Type.Builder colorBuilder = new Type.Builder(mRS, Element.RGBA_8888(mRS));
-      colorBuilder.setX(256).setY(256);
-      mColorBuffer = Allocation.createTyped(mRS, colorBuilder.create(),
-      Allocation.USAGE_GRAPHICS_TEXTURE |
-      Allocation.USAGE_GRAPHICS_RENDER_TARGET);
-
-      /* Set the allocation in the Renderscript runtime */
-      mScript.set_gColorBuffer(mColorBuffer);
-
-      mRS.bindRootScript(mScript);
-  }
-
-    boolean holdingColor[] = new boolean[10];
-    public void newTouchPosition(float x, float y, float pressure, int id) {
-        if (id >= holdingColor.length) {
-            return;
-        }
-        int rate = (int)(pressure * pressure * 500.f);
-        if (rate > 500) {
-            rate = 500;
-        }
-        if (rate > 0) {
-            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
-            holdingColor[id] = true;
-        } else {
-            holdingColor[id] = false;
-        }
-
-    }
-}
-
diff --git a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java b/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java
deleted file mode 100644
index 8636717..0000000
--- a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.rs.fountainfbo;
-
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScriptGL;
-import android.content.Context;
-import android.view.SurfaceHolder;
-import android.view.MotionEvent;
-
-public class FountainFboView extends RSSurfaceView {
-
-    public FountainFboView(Context context) {
-        super(context);
-    }
-
-    private RenderScriptGL mRS;
-    private FountainFboRS mRender;
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new FountainFboRS();
-            mRender.init(mRS, getResources());
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        android.util.Log.e("rs", "onDetachedFromWindow");
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        int act = ev.getActionMasked();
-        if (act == ev.ACTION_UP) {
-            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
-            return false;
-        } else if (act == MotionEvent.ACTION_POINTER_UP) {
-            // only one pointer going up, we can get the index like this
-            int pointerIndex = ev.getActionIndex();
-            int pointerId = ev.getPointerId(pointerIndex);
-            mRender.newTouchPosition(0, 0, 0, pointerId);
-        }
-        int count = ev.getHistorySize();
-        int pcount = ev.getPointerCount();
-
-        for (int p=0; p < pcount; p++) {
-            int id = ev.getPointerId(p);
-            mRender.newTouchPosition(ev.getX(p),
-                                     ev.getY(p),
-                                     ev.getPressure(p),
-                                     id);
-
-            for (int i=0; i < count; i++) {
-                mRender.newTouchPosition(ev.getHistoricalX(p, i),
-                                         ev.getHistoricalY(p, i),
-                                         ev.getHistoricalPressure(p, i),
-                                         id);
-            }
-        }
-        return true;
-    }
-}
-
-
diff --git a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/fountainfbo.rs b/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/fountainfbo.rs
deleted file mode 100644
index 763f6ba..0000000
--- a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/fountainfbo.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Fountain test script
-#pragma version(1)
-
-#pragma rs java_package_name(com.example.android.rs.fountainfbo)
-
-#pragma stateFragment(parent)
-
-#include "rs_graphics.rsh"
-
-static int newPart = 0;
-rs_mesh partMesh;
-rs_program_vertex gProgramVertex;
-
-//allocation for color buffer
-rs_allocation gColorBuffer;
-//fragment shader for rendering without a texture (used for rendering to framebuffer object)
-rs_program_fragment gProgramFragment;
-//fragment shader for rendering with a texture (used for rendering to default framebuffer)
-rs_program_fragment gTextureProgramFragment;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
-    float2 delta;
-    float2 position;
-    uchar4 color;
-} Point_t;
-Point_t *point;
-
-int root() {
-    float dt = min(rsGetDt(), 0.1f);
-    rsgClearColor(0.f, 0.f, 0.f, 1.f);
-    const float height = rsgGetHeight();
-    const int size = rsAllocationGetDimX(rsGetAllocation(point));
-    float dy2 = dt * (10.f);
-    Point_t * p = point;
-    for (int ct=0; ct < size; ct++) {
-        p->delta.y += dy2;
-        p->position += p->delta;
-        if ((p->position.y > height) && (p->delta.y > 0)) {
-            p->delta.y *= -0.3f;
-        }
-        p++;
-    }
-    //Tell Renderscript runtime to render to the frame buffer object
-    rsgBindColorTarget(gColorBuffer, 0);
-
-    //Begin rendering on a white background
-    rsgClearColor(1.f, 1.f, 1.f, 1.f);
-    rsgDrawMesh(partMesh);
-
-    //When done, tell Renderscript runtime to stop rendering to framebuffer object
-    rsgClearAllRenderTargets();
-
-    //Bind a new fragment shader that declares the framebuffer object to be used as a texture
-    rsgBindProgramFragment(gTextureProgramFragment);
-
-    //Bind the framebuffer object to the fragment shader at slot 0 as a texture
-    rsgBindTexture(gTextureProgramFragment, 0, gColorBuffer);
-
-    //Draw a quad using the framebuffer object as the texture
-    float startX = 10, startY = 10;
-    float s = 256;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
-                         startX, startY + s, 0, 0, 0,
-                         startX + s, startY + s, 0, 1, 0,
-                         startX + s, startY, 0, 1, 1);
-
-    //Rebind the original fragment shader to render as normal
-    rsgBindProgramFragment(gProgramFragment);
-
-    //Render the main scene
-    rsgDrawMesh(partMesh);
-
-    return 1;
-}
-
-static float4 partColor[10];
-void addParticles(int rate, float x, float y, int index, bool newColor)
-{
-    if (newColor) {
-        partColor[index].x = rsRand(0.5f, 1.0f);
-        partColor[index].y = rsRand(1.0f);
-        partColor[index].z = rsRand(1.0f);
-    }
-    float rMax = ((float)rate) * 0.02f;
-    int size = rsAllocationGetDimX(rsGetAllocation(point));
-    uchar4 c = rsPackColorTo8888(partColor[index]);
-
-    Point_t * np = &point[newPart];
-    float2 p = {x, y};
-    while (rate--) {
-        float angle = rsRand(3.14f * 2.f);
-        float len = rsRand(rMax);
-        np->delta.x = len * sin(angle);
-        np->delta.y = len * cos(angle);
-        np->position = p;
-        np->color = c;
-        newPart++;
-        np++;
-        if (newPart >= size) {
-            newPart = 0;
-            np = &point[newPart];
-        }
-    }
-}
-
-
diff --git a/tests/RenderScriptTests/Fountain_v11/Android.mk b/tests/RenderScriptTests/Fountain_v11/Android.mk
deleted file mode 100644
index ac2690c..0000000
--- a/tests/RenderScriptTests/Fountain_v11/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Fountain_v11
-LOCAL_SDK_VERSION := 11
-
-include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml b/tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml
deleted file mode 100644
index fcb4faf..0000000
--- a/tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.fountain_v11">
-    <uses-sdk android:minSdkVersion="11" />
-    <application 
-        android:label="Fountain_v11"
-        android:icon="@drawable/test_pattern">
-        <activity android:name="Fountain_v11">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RenderScriptTests/Fountain_v11/_index.html b/tests/RenderScriptTests/Fountain_v11/_index.html
deleted file mode 100644
index 223242f..0000000
--- a/tests/RenderScriptTests/Fountain_v11/_index.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<p>An example that renders many dots on the screen that follow a user's touch. The dots fall 
-to the bottom of the screen when the user releases the finger.</p>
-
-
-
diff --git a/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png b/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java
deleted file mode 100644
index e858100..0000000
--- a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fountain_v11;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-
-public class FountainRS {
-    public static final int PART_COUNT = 50000;
-
-    public FountainRS() {
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private ScriptC_fountain mScript;
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-
-        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setVaryingColor(true);
-        rs.bindProgramFragment(pfb.create());
-
-        ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);//
- //                                                        Allocation.USAGE_GRAPHICS_VERTEX);
-
-        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
-        smb.addVertexAllocation(points.getAllocation());
-        smb.addIndexSetType(Mesh.Primitive.POINT);
-        Mesh sm = smb.create();
-
-        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
-        mScript.set_partMesh(sm);
-        mScript.bind_point(points);
-        mRS.bindRootScript(mScript);
-    }
-
-    boolean holdingColor[] = new boolean[10];
-    public void newTouchPosition(float x, float y, float pressure, int id) {
-        if (id >= holdingColor.length) {
-            return;
-        }
-        int rate = (int)(pressure * pressure * 500.f);
-        if (rate > 500) {
-            rate = 500;
-        }
-        if (rate > 0) {
-            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
-            holdingColor[id] = true;
-        } else {
-            holdingColor[id] = false;
-        }
-
-    }
-}
diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java
deleted file mode 100644
index e82376c..0000000
--- a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fountain_v11;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class FountainView extends RSSurfaceView {
-
-    public FountainView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private FountainRS mRender;
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new FountainRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        int act = ev.getActionMasked();
-        if (act == ev.ACTION_UP) {
-            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
-            return false;
-        } else if (act == MotionEvent.ACTION_POINTER_UP) {
-            // only one pointer going up, we can get the index like this
-            int pointerIndex = ev.getActionIndex();
-            int pointerId = ev.getPointerId(pointerIndex);
-            mRender.newTouchPosition(0, 0, 0, pointerId);
-        }
-        int count = ev.getHistorySize();
-        int pcount = ev.getPointerCount();
-
-        for (int p=0; p < pcount; p++) {
-            int id = ev.getPointerId(p);
-            mRender.newTouchPosition(ev.getX(p),
-                                     ev.getY(p),
-                                     ev.getPressure(p),
-                                     id);
-
-            for (int i=0; i < count; i++) {
-                mRender.newTouchPosition(ev.getHistoricalX(p, i),
-                                         ev.getHistoricalY(p, i),
-                                         ev.getHistoricalPressure(p, i),
-                                         id);
-            }
-        }
-        return true;
-    }
-}
-
-
diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java
deleted file mode 100644
index 2c07b27..0000000
--- a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fountain_v11;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class Fountain_v11 extends Activity {
-    //EventListener mListener = new EventListener();
-
-    private static final String LOG_TAG = "libRS_jni";
-    private static final boolean DEBUG  = false;
-    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private FountainView mView;
-
-    // get the current looper (from your Activity UI thread for instance
-
-
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new FountainView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        Log.e("rs", "onResume");
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        Log.e("rs", "onPause");
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onPause();
-        mView.pause();
-
-
-
-        //Runtime.getRuntime().exit(0);
-    }
-
-
-    static void log(String message) {
-        if (LOG_ENABLED) {
-            Log.v(LOG_TAG, message);
-        }
-    }
-
-
-}
-
diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs
deleted file mode 100644
index 3b6c89a..0000000
--- a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Fountain test script
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.fountain_v11)
-
-#pragma stateFragment(parent)
-
-#include "rs_graphics.rsh"
-
-static int newPart = 0;
-rs_mesh partMesh;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
-    float2 delta;
-    float2 position;
-    uchar4 color;
-} Point_t;
-Point_t *point;
-
-int root() {
-    float dt = min(rsGetDt(), 0.1f);
-    rsgClearColor(0.f, 0.f, 0.f, 1.f);
-    const float height = rsgGetHeight();
-    const int size = rsAllocationGetDimX(rsGetAllocation(point));
-    float dy2 = dt * (10.f);
-    Point_t * p = point;
-    for (int ct=0; ct < size; ct++) {
-        p->delta.y += dy2;
-        p->position += p->delta;
-        if ((p->position.y > height) && (p->delta.y > 0)) {
-            p->delta.y *= -0.3f;
-        }
-        p++;
-    }
-
-    rsgDrawMesh(partMesh);
-    return 1;
-}
-
-static float4 partColor[10];
-void addParticles(int rate, float x, float y, int index, bool newColor)
-{
-    if (newColor) {
-        partColor[index].x = rsRand(0.5f, 1.0f);
-        partColor[index].y = rsRand(1.0f);
-        partColor[index].z = rsRand(1.0f);
-    }
-    float rMax = ((float)rate) * 0.02f;
-    int size = rsAllocationGetDimX(rsGetAllocation(point));
-    uchar4 c = rsPackColorTo8888(partColor[index]);
-
-    Point_t * np = &point[newPart];
-    float2 p = {x, y};
-    while (rate--) {
-        float angle = rsRand(3.14f * 2.f);
-        float len = rsRand(rMax);
-        np->delta.x = len * sin(angle);
-        np->delta.y = len * cos(angle);
-        np->position = p;
-        np->color = c;
-        newPart++;
-        np++;
-        if (newPart >= size) {
-            newPart = 0;
-            np = &point[newPart];
-        }
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index b67afeb..cdcf0ea 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -76,19 +76,18 @@
             Class[] constructorParams = {View.class};
             Object[] constructorArgs = {getDecorContent()};
             LayoutlibCallback callback = params.getLayoutlibCallback();
-            // First try to load the class as was available before appcompat v23.1.1, without
-            // logging warnings.
+
+            // Check if the old action bar class is present.
+            String actionBarClass = WINDOW_ACTION_BAR_CLASS;
             try {
-                mWindowDecorActionBar = callback.loadClass(WINDOW_ACTION_BAR_CLASS,
-                        constructorParams, constructorArgs);
-            } catch (ClassNotFoundException ignore) {
-            }
-            if (mWindowDecorActionBar == null) {
-                // If failed, load the new class, while logging warnings.
-                mWindowDecorActionBar = callback.loadView(WINDOW_ACTION_BAR_CLASS_NEW,
-                        constructorParams, constructorArgs);
+                callback.findClass(actionBarClass);
+            } catch (ClassNotFoundException expected) {
+                // Failed to find the old class, use the newer one.
+                actionBarClass = WINDOW_ACTION_BAR_CLASS_NEW;
             }
 
+            mWindowDecorActionBar = callback.loadView(actionBarClass,
+                    constructorParams, constructorArgs);
             mWindowActionBarClass = mWindowDecorActionBar == null ? null :
                     mWindowDecorActionBar.getClass();
             setupActionBar();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 42e55e2..a6e5fb8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -33,7 +33,6 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.res.ColorStateList;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap_Delegate;
@@ -228,18 +227,16 @@
      * Find the background color for this bar from the theme attributes. Only relevant to StatusBar
      * and NavigationBar.
      * <p/>
-     * Returns null if not found.
+     * Returns 0 if not found.
      *
      * @param colorAttrName the attribute name for the background color
      * @param translucentAttrName the attribute name for the translucency property of the bar.
      *
      * @throws NumberFormatException if color resolved to an invalid string.
      */
-    @Nullable
-    protected Integer getBarColor(@NonNull String colorAttrName,
-            @NonNull String translucentAttrName) {
+    protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) {
         if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) {
-            return null;
+            return 0;
         }
         RenderResources renderResources = getContext().getRenderResources();
         // First check if the bar is translucent.
@@ -254,11 +251,10 @@
         if (transparent) {
             return getColor(renderResources, colorAttrName);
         }
-        return null;
+        return 0;
     }
 
-    @Nullable
-    private static Integer getColor(RenderResources renderResources, String attr) {
+    private static int getColor(RenderResources renderResources, String attr) {
         // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue.
         ResourceValue resource = renderResources.findItemInTheme(attr, true);
         // Form @color/bar to the #AARRGGBB
@@ -279,7 +275,7 @@
                 }
             }
         }
-        return null;
+        return 0;
     }
 
     private ResourceValue getResourceValue(String reference) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
index d50ce23..9c89bfe2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -65,8 +65,8 @@
         super(context, orientation, getShortestWidth(context)>= 600 ? LAYOUT_600DP_XML : LAYOUT_XML,
                 "navigation_bar.xml", simulatedPlatformVersion);
 
-        Integer color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == null ? 0xFF000000 : color);
+        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
+        setBackgroundColor(color == 0 ? 0xFF000000 : color);
 
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 95a5a58..2dc7c65 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -71,9 +71,8 @@
         // FIXME: use FILL_H?
         setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
 
-        Integer color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(
-                color == null ? Config.getStatusBarColor(simulatedPlatformVersion) : color);
+        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
+        setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color);
 
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 2a4f583..0ffa357 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -421,7 +421,8 @@
                     gc.setComposite(AlphaComposite.Src);
 
                     gc.setColor(new Color(0x00000000, true));
-                    gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+                    gc.fillRect(0, 0,
+                            mMeasuredScreenWidth, mMeasuredScreenHeight);
 
                     // done
                     gc.dispose();