Merge "Invalidate when Drawable.setState() returns true"
diff --git a/Android.mk b/Android.mk
index e84b683..505b12d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -173,6 +173,7 @@
 	core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \
 	core/java/android/hardware/input/IInputManager.aidl \
 	core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
+	core/java/android/hardware/input/ITabletModeChangedListener.aidl \
 	core/java/android/hardware/location/IActivityRecognitionHardware.aidl \
 	core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \
 	core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \
diff --git a/api/current.txt b/api/current.txt
index f5e2cda..991756a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3480,14 +3480,14 @@
     method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
     method public final void setMediaController(android.media.session.MediaController);
-    method public final void setProgress(int);
-    method public final void setProgressBarIndeterminate(boolean);
-    method public final void setProgressBarIndeterminateVisibility(boolean);
-    method public final void setProgressBarVisibility(boolean);
+    method public final deprecated void setProgress(int);
+    method public final deprecated void setProgressBarIndeterminate(boolean);
+    method public final deprecated void setProgressBarIndeterminateVisibility(boolean);
+    method public final deprecated void setProgressBarVisibility(boolean);
     method public void setRequestedOrientation(int);
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
-    method public final void setSecondaryProgress(int);
+    method public final deprecated void setSecondaryProgress(int);
     method public void setTaskDescription(android.app.ActivityManager.TaskDescription);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
@@ -12303,6 +12303,7 @@
     method public int getIntrinsicWidth();
     method public int getLayoutDirection();
     method public final int getLevel();
+    method public final float getLevelFloat();
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
@@ -12322,6 +12323,7 @@
     method protected void onBoundsChange(android.graphics.Rect);
     method public boolean onLayoutDirectionChanged(int);
     method protected boolean onLevelChange(int);
+    method protected boolean onLevelChange(float);
     method protected boolean onStateChange(int[]);
     method public static int resolveOpacity(int, int);
     method public void scheduleSelf(java.lang.Runnable, long);
@@ -12339,12 +12341,15 @@
     method public void setHotspotBounds(int, int, int, int);
     method public final boolean setLayoutDirection(int);
     method public final boolean setLevel(int);
+    method public final boolean setLevel(float);
     method public boolean setState(int[]);
     method public void setTint(int);
     method public void setTintList(android.content.res.ColorStateList);
     method public void setTintMode(android.graphics.PorterDuff.Mode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(java.lang.Runnable);
+    field public static final int MAX_LEVEL = 10000; // 0x2710
+    field public static final float MAX_LEVEL_FLOAT = 10000.0f;
   }
 
   public static abstract interface Drawable.Callback {
@@ -37373,23 +37378,23 @@
     field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc
     field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
     field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
-    field public static final int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
+    field public static final deprecated int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
     field public static final int FEATURE_LEFT_ICON = 3; // 0x3
     field public static final int FEATURE_NO_TITLE = 1; // 0x1
     field public static final int FEATURE_OPTIONS_PANEL = 0; // 0x0
-    field public static final int FEATURE_PROGRESS = 2; // 0x2
+    field public static final deprecated int FEATURE_PROGRESS = 2; // 0x2
     field public static final int FEATURE_RIGHT_ICON = 4; // 0x4
     field public static final int FEATURE_SWIPE_TO_DISMISS = 11; // 0xb
     field public static final int ID_ANDROID_CONTENT = 16908290; // 0x1020002
     field public static final java.lang.String NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME = "android:navigation:background";
-    field public static final int PROGRESS_END = 10000; // 0x2710
-    field public static final int PROGRESS_INDETERMINATE_OFF = -4; // 0xfffffffc
-    field public static final int PROGRESS_INDETERMINATE_ON = -3; // 0xfffffffd
-    field public static final int PROGRESS_SECONDARY_END = 30000; // 0x7530
-    field public static final int PROGRESS_SECONDARY_START = 20000; // 0x4e20
-    field public static final int PROGRESS_START = 0; // 0x0
-    field public static final int PROGRESS_VISIBILITY_OFF = -2; // 0xfffffffe
-    field public static final int PROGRESS_VISIBILITY_ON = -1; // 0xffffffff
+    field public static final deprecated int PROGRESS_END = 10000; // 0x2710
+    field public static final deprecated int PROGRESS_INDETERMINATE_OFF = -4; // 0xfffffffc
+    field public static final deprecated int PROGRESS_INDETERMINATE_ON = -3; // 0xfffffffd
+    field public static final deprecated int PROGRESS_SECONDARY_END = 30000; // 0x7530
+    field public static final deprecated int PROGRESS_SECONDARY_START = 20000; // 0x4e20
+    field public static final deprecated int PROGRESS_START = 0; // 0x0
+    field public static final deprecated int PROGRESS_VISIBILITY_OFF = -2; // 0xfffffffe
+    field public static final deprecated int PROGRESS_VISIBILITY_ON = -1; // 0xffffffff
     field public static final java.lang.String STATUS_BAR_BACKGROUND_TRANSITION_NAME = "android:status:background";
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index ec8f952..b8e5600 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3583,14 +3583,14 @@
     method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
     method public final void setMediaController(android.media.session.MediaController);
-    method public final void setProgress(int);
-    method public final void setProgressBarIndeterminate(boolean);
-    method public final void setProgressBarIndeterminateVisibility(boolean);
-    method public final void setProgressBarVisibility(boolean);
+    method public final deprecated void setProgress(int);
+    method public final deprecated void setProgressBarIndeterminate(boolean);
+    method public final deprecated void setProgressBarIndeterminateVisibility(boolean);
+    method public final deprecated void setProgressBarVisibility(boolean);
     method public void setRequestedOrientation(int);
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
-    method public final void setSecondaryProgress(int);
+    method public final deprecated void setSecondaryProgress(int);
     method public void setTaskDescription(android.app.ActivityManager.TaskDescription);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
@@ -12640,6 +12640,7 @@
     method public int getIntrinsicWidth();
     method public int getLayoutDirection();
     method public final int getLevel();
+    method public final float getLevelFloat();
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
@@ -12659,6 +12660,7 @@
     method protected void onBoundsChange(android.graphics.Rect);
     method public boolean onLayoutDirectionChanged(int);
     method protected boolean onLevelChange(int);
+    method protected boolean onLevelChange(float);
     method protected boolean onStateChange(int[]);
     method public static int resolveOpacity(int, int);
     method public void scheduleSelf(java.lang.Runnable, long);
@@ -12676,12 +12678,15 @@
     method public void setHotspotBounds(int, int, int, int);
     method public final boolean setLayoutDirection(int);
     method public final boolean setLevel(int);
+    method public final boolean setLevel(float);
     method public boolean setState(int[]);
     method public void setTint(int);
     method public void setTintList(android.content.res.ColorStateList);
     method public void setTintMode(android.graphics.PorterDuff.Mode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(java.lang.Runnable);
+    field public static final int MAX_LEVEL = 10000; // 0x2710
+    field public static final float MAX_LEVEL_FLOAT = 10000.0f;
   }
 
   public static abstract interface Drawable.Callback {
@@ -39668,23 +39673,23 @@
     field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc
     field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
     field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
-    field public static final int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
+    field public static final deprecated int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
     field public static final int FEATURE_LEFT_ICON = 3; // 0x3
     field public static final int FEATURE_NO_TITLE = 1; // 0x1
     field public static final int FEATURE_OPTIONS_PANEL = 0; // 0x0
-    field public static final int FEATURE_PROGRESS = 2; // 0x2
+    field public static final deprecated int FEATURE_PROGRESS = 2; // 0x2
     field public static final int FEATURE_RIGHT_ICON = 4; // 0x4
     field public static final int FEATURE_SWIPE_TO_DISMISS = 11; // 0xb
     field public static final int ID_ANDROID_CONTENT = 16908290; // 0x1020002
     field public static final java.lang.String NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME = "android:navigation:background";
-    field public static final int PROGRESS_END = 10000; // 0x2710
-    field public static final int PROGRESS_INDETERMINATE_OFF = -4; // 0xfffffffc
-    field public static final int PROGRESS_INDETERMINATE_ON = -3; // 0xfffffffd
-    field public static final int PROGRESS_SECONDARY_END = 30000; // 0x7530
-    field public static final int PROGRESS_SECONDARY_START = 20000; // 0x4e20
-    field public static final int PROGRESS_START = 0; // 0x0
-    field public static final int PROGRESS_VISIBILITY_OFF = -2; // 0xfffffffe
-    field public static final int PROGRESS_VISIBILITY_ON = -1; // 0xffffffff
+    field public static final deprecated int PROGRESS_END = 10000; // 0x2710
+    field public static final deprecated int PROGRESS_INDETERMINATE_OFF = -4; // 0xfffffffc
+    field public static final deprecated int PROGRESS_INDETERMINATE_ON = -3; // 0xfffffffd
+    field public static final deprecated int PROGRESS_SECONDARY_END = 30000; // 0x7530
+    field public static final deprecated int PROGRESS_SECONDARY_START = 20000; // 0x4e20
+    field public static final deprecated int PROGRESS_START = 0; // 0x0
+    field public static final deprecated int PROGRESS_VISIBILITY_OFF = -2; // 0xfffffffe
+    field public static final deprecated int PROGRESS_VISIBILITY_ON = -1; // 0xffffffff
     field public static final java.lang.String STATUS_BAR_BACKGROUND_TRANSITION_NAME = "android:status:background";
   }
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a4e1135..73c3786 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5436,7 +5436,9 @@
      * via {@link #requestWindowFeature(int)}.
      *
      * @param visible Whether to show the progress bars in the title.
+     * @deprecated No longer supported starting in API 21.
      */
+    @Deprecated
     public final void setProgressBarVisibility(boolean visible) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON :
             Window.PROGRESS_VISIBILITY_OFF);
@@ -5449,7 +5451,9 @@
      * via {@link #requestWindowFeature(int)}.
      *
      * @param visible Whether to show the progress bars in the title.
+     * @deprecated No longer supported starting in API 21.
      */
+    @Deprecated
     public final void setProgressBarIndeterminateVisibility(boolean visible) {
         getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
                 visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF);
@@ -5463,7 +5467,9 @@
      * via {@link #requestWindowFeature(int)}.
      *
      * @param indeterminate Whether the horizontal progress bar should be indeterminate.
+     * @deprecated No longer supported starting in API 21.
      */
+    @Deprecated
     public final void setProgressBarIndeterminate(boolean indeterminate) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                 indeterminate ? Window.PROGRESS_INDETERMINATE_ON
@@ -5479,7 +5485,9 @@
      * @param progress The progress for the progress bar. Valid ranges are from
      *            0 to 10000 (both inclusive). If 10000 is given, the progress
      *            bar will be completely filled and will fade out.
+     * @deprecated No longer supported starting in API 21.
      */
+    @Deprecated
     public final void setProgress(int progress) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START);
     }
@@ -5496,7 +5504,9 @@
      *
      * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from
      *            0 to 10000 (both inclusive).
+     * @deprecated No longer supported starting in API 21.
      */
+    @Deprecated
     public final void setSecondaryProgress(int secondaryProgress) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                 secondaryProgress + Window.PROGRESS_SECONDARY_START);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 580f721..eeae20f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1108,7 +1108,7 @@
      * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}.
      *
      * @return Returns a list of RecentTaskInfo records describing each of
-     * the recent tasks.
+     * the recent tasks. Most recently activated tasks go first.
      *
      * @hide
      */
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 2406985..933f98d 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IRemoteCallback;
@@ -59,6 +60,13 @@
     public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
 
     /**
+     * The bounds that the activity should be started in. Set to null explicitly
+     * for full screen. If the key is not found, previous bounds will be preserved.
+     * @hide
+     */
+    public static final String KEY_BOUNDS = "android:activity.bounds";
+
+    /**
      * Type of animation that arguments specify.
      * @hide
      */
@@ -163,6 +171,8 @@
     public static final int ANIM_CLIP_REVEAL = 11;
 
     private String mPackageName;
+    private boolean mHasBounds;
+    private Rect mBounds;
     private int mAnimationType = ANIM_NONE;
     private int mCustomEnterResId;
     private int mCustomExitResId;
@@ -631,6 +641,10 @@
         } catch (RuntimeException e) {
             Slog.w(TAG, e);
         }
+        mHasBounds = opts.containsKey(KEY_BOUNDS);
+        if (mHasBounds) {
+            mBounds = opts.getParcelable(KEY_BOUNDS);
+        }
         mAnimationType = opts.getInt(KEY_ANIM_TYPE);
         switch (mAnimationType) {
             case ANIM_CUSTOM:
@@ -677,11 +691,28 @@
     }
 
     /** @hide */
+    public ActivityOptions setBounds(Rect bounds) {
+        mHasBounds = true;
+        mBounds = bounds;
+        return this;
+    }
+
+    /** @hide */
     public String getPackageName() {
         return mPackageName;
     }
 
     /** @hide */
+    public boolean hasBounds() {
+        return mHasBounds;
+    }
+
+    /** @hide */
+    public Rect getBounds(){
+        return mBounds;
+    }
+
+    /** @hide */
     public int getAnimationType() {
         return mAnimationType;
     }
@@ -867,6 +898,9 @@
         if (mPackageName != null) {
             b.putString(KEY_PACKAGE_NAME, mPackageName);
         }
+        if (mHasBounds) {
+            b.putParcelable(KEY_BOUNDS, mBounds);
+        }
         b.putInt(KEY_ANIM_TYPE, mAnimationType);
         if (mUsageTimeReport != null) {
             b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e15ba74..67dee7f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4593,27 +4593,6 @@
         }
         updateDefaultDensity();
 
-        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
-        if (!Process.isIsolated()) {
-            final File cacheDir = appContext.getCacheDir();
-
-            if (cacheDir != null) {
-                // Provide a usable directory for temporary files
-                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
-            } else {
-                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property due to missing cache directory");
-            }
-
-            // Use codeCacheDir to store generated/compiled graphics code
-            final File codeCacheDir = appContext.getCodeCacheDir();
-            if (codeCacheDir != null) {
-                setupGraphicsSupport(data.info, codeCacheDir);
-            } else {
-                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
-            }
-        }
-
-
         final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
         DateFormat.set24HourTimePref(is24Hr);
 
@@ -4685,29 +4664,28 @@
         /**
          * Initialize the default http proxy in this process for the reasons we set the time zone.
          */
-        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
         if (b != null) {
             // In pre-boot mode (doing initial launch to collect password), not
             // all system is up.  This includes the connectivity service, so don't
             // crash if we can't get it.
-            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
+            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
             try {
                 final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
                 Proxy.setHttpProxySystemProperty(proxyInfo);
             } catch (RemoteException e) {}
         }
 
+        // Instrumentation info affects the class loader, so load it before
+        // setting up the app context.
+        final InstrumentationInfo ii;
         if (data.instrumentationName != null) {
-            InstrumentationInfo ii = null;
             try {
-                ii = appContext.getPackageManager().
-                    getInstrumentationInfo(data.instrumentationName, 0);
+                ii = new ApplicationPackageManager(null, getPackageManager())
+                        .getInstrumentationInfo(data.instrumentationName, 0);
             } catch (PackageManager.NameNotFoundException e) {
-            }
-            if (ii == null) {
                 throw new RuntimeException(
-                    "Unable to find instrumentation info for: "
-                    + data.instrumentationName);
+                        "Unable to find instrumentation info for: " + data.instrumentationName);
             }
 
             mInstrumentationPackageName = ii.packageName;
@@ -4717,13 +4695,32 @@
             mInstrumentedAppDir = data.info.getAppDir();
             mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
             mInstrumentedLibDir = data.info.getLibDir();
+        } else {
+            ii = null;
+        }
 
-            // The app context's info was created against this thread, but
-            // the class loader may have already been loaded and cached with
-            // outdated paths. Clear it so we can load it again using the
-            // instrumentation paths.
-            data.info.clearClassLoader();
+        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
+        if (!Process.isIsolated()) {
+            final File cacheDir = appContext.getCacheDir();
+            if (cacheDir != null) {
+                // Provide a usable directory for temporary files
+                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+            } else {
+                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
+                        + "due to missing cache directory");
+            }
 
+            // Use codeCacheDir to store generated/compiled graphics code
+            final File codeCacheDir = appContext.getCodeCacheDir();
+            if (codeCacheDir != null) {
+                setupGraphicsSupport(data.info, codeCacheDir);
+            } else {
+                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
+            }
+        }
+
+        // Continue loading instrumentation.
+        if (ii != null) {
             final ApplicationInfo instrApp = new ApplicationInfo();
             instrApp.packageName = ii.packageName;
             instrApp.sourceDir = ii.sourceDir;
@@ -4732,13 +4729,13 @@
             instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
             instrApp.dataDir = ii.dataDir;
             instrApp.nativeLibraryDir = ii.nativeLibraryDir;
-            LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
+
+            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                     appContext.getClassLoader(), false, true, false);
-            ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
+            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
 
             try {
-
-                java.lang.ClassLoader cl = instrContext.getClassLoader();
+                final ClassLoader cl = instrContext.getClassLoader();
                 mInstrumentation = (Instrumentation)
                     cl.loadClass(data.instrumentationName.getClassName()).newInstance();
             } catch (Exception e) {
@@ -4747,18 +4744,17 @@
                     + data.instrumentationName + ": " + e.toString(), e);
             }
 
-            mInstrumentation.init(this, instrContext, appContext,
-                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
-                   data.instrumentationUiAutomationConnection);
+            final ComponentName component = new ComponentName(ii.packageName, ii.name);
+            mInstrumentation.init(this, instrContext, appContext, component,
+                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
 
             if (mProfiler.profileFile != null && !ii.handleProfiling
                     && mProfiler.profileFd == null) {
                 mProfiler.handlingProfiling = true;
-                File file = new File(mProfiler.profileFile);
+                final File file = new File(mProfiler.profileFile);
                 file.getParentFile().mkdirs();
                 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
             }
-
         } else {
             mInstrumentation = new Instrumentation();
         }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3b1c60b..c2bf28a 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -255,13 +255,6 @@
         return ai.sharedLibraryFiles;
     }
 
-    /** @hide */
-    public void clearClassLoader() {
-        synchronized (this) {
-            mClassLoader = null;
-        }
-    }
-
     public ClassLoader getClassLoader() {
         synchronized (this) {
             if (mClassLoader != null) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 3ecbaa0..927c02f 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1049,7 +1049,7 @@
         }
         fixUpLocaleList();
         delta.fixUpLocaleList();
-        if (!mLocaleList.equals(delta.mLocaleList)) {
+        if (!delta.mLocaleList.isEmpty() && !mLocaleList.equals(delta.mLocaleList)) {
             changed |= ActivityInfo.CONFIG_LOCALE;
             changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
         }
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 465d142..c8b45c7 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -19,6 +19,7 @@
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.IInputDevicesChangedListener;
+import android.hardware.input.ITabletModeChangedListener;
 import android.hardware.input.TouchCalibration;
 import android.os.IBinder;
 import android.view.InputDevice;
@@ -60,6 +61,9 @@
     // Registers an input devices changed listener.
     void registerInputDevicesChangedListener(IInputDevicesChangedListener listener);
 
+    // Registers a tablet mode change listener
+    void registerTabletModeChangedListener(ITabletModeChangedListener listener);
+
     // Input device vibrator control.
     void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token);
     void cancelVibrate(int deviceId, IBinder token);
diff --git a/core/java/android/hardware/input/ITabletModeChangedListener.aidl b/core/java/android/hardware/input/ITabletModeChangedListener.aidl
new file mode 100644
index 0000000..a8559a7
--- /dev/null
+++ b/core/java/android/hardware/input/ITabletModeChangedListener.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 android.hardware.input;
+
+/** @hide */
+interface ITabletModeChangedListener {
+    /* Called when the device enters or exits tablet mode. */
+    oneway void onTabletModeChanged(long whenNanos, boolean inTabletMode);
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 4292050..bae5757 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,6 +16,7 @@
 
 package android.hardware.input;
 
+import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
 
 import android.annotation.SdkConstant;
@@ -29,6 +30,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
@@ -38,6 +40,7 @@
 import android.view.InputEvent;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Provides information about input devices and available key layouts.
@@ -67,6 +70,11 @@
     private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners =
             new ArrayList<InputDeviceListenerDelegate>();
 
+    // Guarded by mTabletModeLock
+    private final Object mTabletModeLock = new Object();
+    private TabletModeChangedListener mTabletModeChangedListener;
+    private List<OnTabletModeChangedListenerDelegate> mOnTabletModeChangedListeners;
+
     /**
      * Broadcast Action: Query available keyboard layouts.
      * <p>
@@ -332,6 +340,72 @@
     }
 
     /**
+     * Register a tablet mode changed listener.
+     *
+     * @param listener The listener to register.
+     * @param handler The handler on which the listener should be invoked, or null
+     * if the listener should be invoked on the calling thread's looper.
+     * @hide
+     */
+    public void registerOnTabletModeChangedListener(
+            OnTabletModeChangedListener listener, Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+        synchronized (mTabletModeLock) {
+            if (mOnTabletModeChangedListeners == null) {
+                initializeTabletModeListenerLocked();
+            }
+            int idx = findOnTabletModeChangedListenerLocked(listener);
+            if (idx < 0) {
+                OnTabletModeChangedListenerDelegate d =
+                    new OnTabletModeChangedListenerDelegate(listener, handler);
+                mOnTabletModeChangedListeners.add(d);
+            }
+        }
+    }
+
+    /**
+     * Unregister a tablet mode changed listener.
+     *
+     * @param listener The listener to unregister.
+     * @hide
+     */
+    public void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+        synchronized (mTabletModeLock) {
+            int idx = findOnTabletModeChangedListenerLocked(listener);
+            if (idx >= 0) {
+                OnTabletModeChangedListenerDelegate d = mOnTabletModeChangedListeners.remove(idx);
+                d.removeCallbacksAndMessages(null);
+            }
+        }
+    }
+
+    private void initializeTabletModeListenerLocked() {
+        final TabletModeChangedListener listener = new TabletModeChangedListener();
+        try {
+            mIm.registerTabletModeChangedListener(listener);
+        } catch (RemoteException ex) {
+            throw new RuntimeException("Could not register tablet mode changed listener", ex);
+        }
+        mTabletModeChangedListener = listener;
+        mOnTabletModeChangedListeners = new ArrayList<>();
+    }
+
+    private int findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener) {
+        final int N = mOnTabletModeChangedListeners.size();
+        for (int i = 0; i < N; i++) {
+            if (mOnTabletModeChangedListeners.get(i).mListener == listener) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
      * Gets information about all supported keyboard layouts.
      * <p>
      * The input manager consults the built-in keyboard layouts as well
@@ -770,6 +844,22 @@
         return false;
     }
 
+
+    private void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+        if (DEBUG) {
+            Log.d(TAG, "Received tablet mode changed: "
+                    + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode);
+        }
+        synchronized (mTabletModeLock) {
+            final int N = mOnTabletModeChangedListeners.size();
+            for (int i = 0; i < N; i++) {
+                OnTabletModeChangedListenerDelegate listener =
+                        mOnTabletModeChangedListeners.get(i);
+                listener.sendTabletModeChanged(whenNanos, inTabletMode);
+            }
+        }
+    }
+
     /**
      * Gets a vibrator service associated with an input device, assuming it has one.
      * @return The vibrator, never null.
@@ -839,6 +929,57 @@
         }
     }
 
+    /** @hide */
+    public interface OnTabletModeChangedListener {
+        /**
+         * Called whenever the device goes into or comes out of tablet mode.
+         *
+         * @param whenNanos The time at which the device transitioned into or
+         * out of tablet mode. This is given in nanoseconds in the
+         * {@link SystemClock#uptimeMillis} time base.
+         */
+        void onTabletModeChanged(long whenNanos, boolean inTabletMode);
+    }
+
+    private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub {
+        @Override
+        public void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+            InputManager.this.onTabletModeChanged(whenNanos, inTabletMode);
+        }
+    }
+
+    private static final class OnTabletModeChangedListenerDelegate extends Handler {
+        private static final int MSG_TABLET_MODE_CHANGED = 0;
+
+        public final OnTabletModeChangedListener mListener;
+
+        public OnTabletModeChangedListenerDelegate(
+                OnTabletModeChangedListener listener, Handler handler) {
+            super(handler != null ? handler.getLooper() : Looper.myLooper());
+            mListener = listener;
+        }
+
+        public void sendTabletModeChanged(long whenNanos, boolean inTabletMode) {
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
+            args.argi2 = (int) (whenNanos >> 32);
+            args.arg1 = (Boolean) inTabletMode;
+            obtainMessage(MSG_TABLET_MODE_CHANGED, args).sendToTarget();
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_TABLET_MODE_CHANGED:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32);
+                    boolean inTabletMode = (boolean) args.arg1;
+                    mListener.onTabletModeChanged(whenNanos, inTabletMode);
+                    break;
+            }
+        }
+    }
+
     private final class InputDeviceVibrator extends Vibrator {
         private final int mDeviceId;
         private final Binder mToken;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d4e6c82..4055836 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2259,6 +2259,7 @@
         private final AtomicInteger mRefCount;
         private static final String TAG = "ConnectivityManager.CallbackHandler";
         private final ConnectivityManager mCm;
+        private static final boolean DBG = false;
 
         CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
                 AtomicInteger refCount, ConnectivityManager cm) {
@@ -2270,7 +2271,7 @@
 
         @Override
         public void handleMessage(Message message) {
-            Log.d(TAG, "CM callback handler got msg " + message.what);
+            if (DBG) Log.d(TAG, "CM callback handler got msg " + message.what);
             NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class);
             Network network = (Network) getObject(message, Network.class);
             switch (message.what) {
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index e742f98..70cff00 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -108,6 +108,12 @@
     public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis);
 
     /**
+     * Used by the window manager to tell the power manager that the user is no longer actively
+     * using the device.
+     */
+    public abstract void setUserInactiveOverrideFromWindowManager();
+
+    /**
      * Used by device administration to set the maximum screen off timeout.
      *
      * This method must only be called by the device administration policy manager.
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 6d89824..61ba590 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -788,8 +788,11 @@
     /** Key code constant: Step backward media key.
      * Steps media backward, one frame at a time. */
     public static final int KEYCODE_MEDIA_STEP_BACKWARD = 275;
+    /** Key code constant: put device to sleep unless a wakelock is held.
+     * @hide */
+    public static final int KEYCODE_SOFT_SLEEP = 276;
 
-    private static final int LAST_KEYCODE = KEYCODE_MEDIA_STEP_BACKWARD;
+    private static final int LAST_KEYCODE = KEYCODE_SOFT_SLEEP;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 5970c3f..bcf9b2c 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -484,6 +484,7 @@
         public boolean secure;
         public long appVsyncOffsetNanos;
         public long presentationDeadlineNanos;
+        public int colorTransform;
 
         public PhysicalDisplayInfo() {
         }
@@ -507,7 +508,8 @@
                     && yDpi == other.yDpi
                     && secure == other.secure
                     && appVsyncOffsetNanos == other.appVsyncOffsetNanos
-                    && presentationDeadlineNanos == other.presentationDeadlineNanos;
+                    && presentationDeadlineNanos == other.presentationDeadlineNanos
+                    && colorTransform == other.colorTransform;
         }
 
         @Override
@@ -525,6 +527,7 @@
             secure = other.secure;
             appVsyncOffsetNanos = other.appVsyncOffsetNanos;
             presentationDeadlineNanos = other.presentationDeadlineNanos;
+            colorTransform = other.colorTransform;
         }
 
         // For debugging purposes
@@ -533,7 +536,8 @@
             return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
                     + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
                     + ", appVsyncOffset " + appVsyncOffsetNanos
-                    + ", bufferDeadline " + presentationDeadlineNanos + "}";
+                    + ", bufferDeadline " + presentationDeadlineNanos
+                    + ", colorTransform " + colorTransform + "}";
         }
     }
 
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 7a3d882..5893f4a 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -58,14 +58,28 @@
     /** Flag for the "no title" feature, turning off the title at the top
      *  of the screen. */
     public static final int FEATURE_NO_TITLE = 1;
-    /** Flag for the progress indicator feature */
+
+    /**
+     * Flag for the progress indicator feature.
+     *
+     * @deprecated No longer supported starting in API 21.
+     */
+    @Deprecated
     public static final int FEATURE_PROGRESS = 2;
+
     /** Flag for having an icon on the left side of the title bar */
     public static final int FEATURE_LEFT_ICON = 3;
     /** Flag for having an icon on the right side of the title bar */
     public static final int FEATURE_RIGHT_ICON = 4;
-    /** Flag for indeterminate progress */
+
+    /**
+     * Flag for indeterminate progress.
+     *
+     * @deprecated No longer supported starting in API 21.
+     */
+    @Deprecated
     public static final int FEATURE_INDETERMINATE_PROGRESS = 5;
+
     /** Flag for the context menu.  This is enabled by default. */
     public static final int FEATURE_CONTEXT_MENU = 6;
     /** Flag for custom title. You cannot combine this feature with other title features. */
@@ -133,21 +147,76 @@
      */
     public static final int FEATURE_MAX = FEATURE_ACTIVITY_TRANSITIONS;
 
-    /** Flag for setting the progress bar's visibility to VISIBLE */
+    /**
+     * Flag for setting the progress bar's visibility to VISIBLE.
+     *
+     * @deprecated {@link #FEATURE_PROGRESS} and related methods are no longer
+     *             supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_VISIBILITY_ON = -1;
-    /** Flag for setting the progress bar's visibility to GONE */
+
+    /**
+     * Flag for setting the progress bar's visibility to GONE.
+     *
+     * @deprecated {@link #FEATURE_PROGRESS} and related methods are no longer
+     *             supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_VISIBILITY_OFF = -2;
-    /** Flag for setting the progress bar's indeterminate mode on */
+
+    /**
+     * Flag for setting the progress bar's indeterminate mode on.
+     *
+     * @deprecated {@link #FEATURE_INDETERMINATE_PROGRESS} and related methods
+     *             are no longer supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_INDETERMINATE_ON = -3;
-    /** Flag for setting the progress bar's indeterminate mode off */
+
+    /**
+     * Flag for setting the progress bar's indeterminate mode off.
+     *
+     * @deprecated {@link #FEATURE_INDETERMINATE_PROGRESS} and related methods
+     *             are no longer supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_INDETERMINATE_OFF = -4;
-    /** Starting value for the (primary) progress */
+
+    /**
+     * Starting value for the (primary) progress.
+     *
+     * @deprecated {@link #FEATURE_PROGRESS} and related methods are no longer
+     *             supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_START = 0;
-    /** Ending value for the (primary) progress */
+
+    /**
+     * Ending value for the (primary) progress.
+     *
+     * @deprecated {@link #FEATURE_PROGRESS} and related methods are no longer
+     *             supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_END = 10000;
-    /** Lowest possible value for the secondary progress */
+
+    /**
+     * Lowest possible value for the secondary progress.
+     *
+     * @deprecated {@link #FEATURE_PROGRESS} and related methods are no longer
+     *             supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_SECONDARY_START = 20000;
-    /** Highest possible value for the secondary progress */
+
+    /**
+     * Highest possible value for the secondary progress.
+     *
+     * @deprecated {@link #FEATURE_PROGRESS} and related methods are no longer
+     *             supported starting in API 21.
+     */
+    @Deprecated
     public static final int PROGRESS_SECONDARY_END = 30000;
 
     /**
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index e77b862..72971e8 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -199,10 +199,7 @@
                 } else {
                     userId = UserHandle.myUserId();
                 }
-                IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
-                IAccessibilityManager service = iBinder == null
-                        ? null : IAccessibilityManager.Stub.asInterface(iBinder);
-                sInstance = new AccessibilityManager(context, service, userId);
+                sInstance = new AccessibilityManager(context, null, userId);
             }
         }
         return sInstance;
@@ -219,10 +216,9 @@
      */
     public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
         mHandler = new MyHandler(context.getMainLooper());
-        mService = service;
         mUserId = userId;
         synchronized (mLock) {
-            tryConnectToServiceLocked();
+            tryConnectToServiceLocked(service);
         }
     }
 
@@ -612,17 +608,20 @@
 
     private  IAccessibilityManager getServiceLocked() {
         if (mService == null) {
-            tryConnectToServiceLocked();
+            tryConnectToServiceLocked(null);
         }
         return mService;
     }
 
-    private void tryConnectToServiceLocked() {
-        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
-        if (iBinder == null) {
-            return;
+    private void tryConnectToServiceLocked(IAccessibilityManager service) {
+        if (service == null) {
+            IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
+            if (iBinder == null) {
+                return;
+            }
+            service = IAccessibilityManager.Stub.asInterface(iBinder);
         }
-        IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
+
         try {
             final int stateFlags = service.addClient(mClient, mUserId);
             setStateLocked(stateFlags);
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 959d249..af73097 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -179,19 +179,15 @@
 
     static void preload() {
         Log.d(TAG, "begin preload");
-        try {
-            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
-            preloadClasses();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-        }
-        try {
-            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
-            preloadResources();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-        }
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
+        preloadClasses();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
+        preloadResources();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
         preloadOpenGL();
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
         preloadSharedLibraries();
         preloadTextResources();
         // Ask the WebViewFactory to do any initialization that must run in the zygote process,
@@ -275,8 +271,8 @@
                     continue;
                 }
 
+                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
                 try {
-                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
                     if (false) {
                         Log.v(TAG, "Preloading " + line + "...");
                     }
@@ -300,9 +296,8 @@
                         throw (RuntimeException) t;
                     }
                     throw new RuntimeException(t);
-                } finally {
-                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
             }
 
             Log.i(TAG, "...preloaded " + count + " classes in "
@@ -579,57 +574,49 @@
 
     public static void main(String argv[]) {
         try {
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
+            RuntimeInit.enableDdms();
+            // Start profiling the zygote initialization.
+            SamplingProfilerIntegration.start();
+
             boolean startSystemServer = false;
             String socketName = "zygote";
             String abiList = null;
-            try {
-                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
-                RuntimeInit.enableDdms();
-                // Start profiling the zygote initialization.
-                SamplingProfilerIntegration.start();
-
-                for (int i = 1; i < argv.length; i++) {
-                    if ("start-system-server".equals(argv[i])) {
-                        startSystemServer = true;
-                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
-                        abiList = argv[i].substring(ABI_LIST_ARG.length());
-                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
-                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
-                    } else {
-                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
-                    }
+            for (int i = 1; i < argv.length; i++) {
+                if ("start-system-server".equals(argv[i])) {
+                    startSystemServer = true;
+                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
+                    abiList = argv[i].substring(ABI_LIST_ARG.length());
+                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
+                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
+                } else {
+                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                 }
-
-                if (abiList == null) {
-                    throw new RuntimeException("No ABI list supplied.");
-                }
-
-                registerZygoteSocket(socketName);
-                try {
-                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
-                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
-                            SystemClock.uptimeMillis());
-                    preload();
-                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
-                            SystemClock.uptimeMillis());
-                } finally {
-                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-                }
-
-                // Finish profiling the zygote initialization.
-                SamplingProfilerIntegration.writeZygoteSnapshot();
-
-                // Do an initial gc to clean up after startup
-                try {
-                    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
-                    gcAndFinalize();
-                } finally {
-                    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
-                }
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
             }
 
+            if (abiList == null) {
+                throw new RuntimeException("No ABI list supplied.");
+            }
+
+            registerZygoteSocket(socketName);
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
+            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
+                SystemClock.uptimeMillis());
+            preload();
+            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
+                SystemClock.uptimeMillis());
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+
+            // Finish profiling the zygote initialization.
+            SamplingProfilerIntegration.writeZygoteSnapshot();
+
+            // Do an initial gc to clean up after startup
+            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
+            gcAndFinalize();
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+
+            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+
             // Disable tracing so that forked processes do not inherit stale tracing tags from
             // Zygote.
             Trace.setTracingEnabled(false);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 051845f..d96a909 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -232,7 +232,7 @@
     public void reportFailedPasswordAttempt(int userId) {
         getDevicePolicyManager().reportFailedPasswordAttempt(userId);
         getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
-        requireCredentialEntry(userId);
+        requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL, userId);
     }
 
     public void reportSuccessfulPasswordAttempt(int userId) {
@@ -1290,10 +1290,17 @@
          */
         public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8;
 
+        /**
+         * Some authentication is required because the user has entered a wrong credential.
+         */
+        public static final int SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL = 0x10;
+
         public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
 
-        final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
+        private static final int ALLOWING_FINGERPRINT = STRONG_AUTH_NOT_REQUIRED
+                | SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL;
 
+        private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
         private final H mHandler;
 
         public StrongAuthTracker() {
@@ -1332,7 +1339,7 @@
          * current strong authentication requirements.
          */
         public boolean isFingerprintAllowedForUser(int userId) {
-            return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED;
+            return (getStrongAuthForUser(userId) & ~ALLOWING_FINGERPRINT) == 0;
         }
 
         /**
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 54be410..d1acb59 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -57,6 +57,7 @@
     jfieldID secure;
     jfieldID appVsyncOffsetNanos;
     jfieldID presentationDeadlineNanos;
+    jfieldID colorTransform;
 } gPhysicalDisplayInfoClassInfo;
 
 static struct {
@@ -394,6 +395,8 @@
                 info.appVsyncOffset);
         env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
                 info.presentationDeadline);
+        env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform,
+                info.colorTransform);
         env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
         env->DeleteLocalRef(infoObj);
     }
@@ -656,6 +659,8 @@
             clazz, "appVsyncOffsetNanos", "J");
     gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env,
             clazz, "presentationDeadlineNanos", "J");
+    gPhysicalDisplayInfoClassInfo.colorTransform = GetFieldIDOrDie(env, clazz,
+            "colorTransform", "I");
 
     jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
     gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b0621e9..d6657dd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2069,6 +2069,12 @@
     <permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to monitor changes in tablet mode.
+         <p>Not for use by third-party applications.
+         @hide -->
+    <permission android:name="android.permission.TABLET_MODE_LISTENER"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to request installing packages. Apps
          targeting APIs greater than 22 must hold this permission in
          order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.
diff --git a/core/res/res/anim/ic_checkbox_to_checked_box_inner_merged_animation.xml b/core/res/res/anim/btn_checkbox_to_checked_box_inner_merged_animation.xml
similarity index 92%
rename from core/res/res/anim/ic_checkbox_to_checked_box_inner_merged_animation.xml
rename to core/res/res/anim/btn_checkbox_to_checked_box_inner_merged_animation.xml
index e522453..11d018b 100644
--- a/core/res/res/anim/ic_checkbox_to_checked_box_inner_merged_animation.xml
+++ b/core/res/res/anim/btn_checkbox_to_checked_box_inner_merged_animation.xml
@@ -21,7 +21,7 @@
         android:valueFrom="M -7.0,-7.0 l 14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
         android:valueTo="M 0.0,-0.05 l 0.0,0.0 c 0.02761423749,0.0 0.05,0.02238576251 0.05,0.05 l 0.0,0.0 c 0.0,0.02761423749 -0.02238576251,0.05 -0.05,0.05 l 0.0,0.0 c -0.02761423749,0.0 -0.05,-0.02238576251 -0.05,-0.05 l 0.0,0.0 c 0.0,-0.02761423749 0.02238576251,-0.05 0.05,-0.05 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
         android:valueType="pathType"
-        android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+        android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1" />
     <set android:ordering="sequentially">
         <objectAnimator
             android:duration="166"
@@ -34,6 +34,6 @@
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
             android:valueTo="0.0"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_0" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_0" />
     </set>
 </set>
diff --git a/core/res/res/anim/ic_checkbox_to_checked_box_outer_merged_animation.xml b/core/res/res/anim/btn_checkbox_to_checked_box_outer_merged_animation.xml
similarity index 95%
rename from core/res/res/anim/ic_checkbox_to_checked_box_outer_merged_animation.xml
rename to core/res/res/anim/btn_checkbox_to_checked_box_outer_merged_animation.xml
index 628e967..9e90ba0 100644
--- a/core/res/res/anim/ic_checkbox_to_checked_box_outer_merged_animation.xml
+++ b/core/res/res/anim/btn_checkbox_to_checked_box_outer_merged_animation.xml
@@ -29,7 +29,7 @@
             android:valueFrom="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
             android:valueTo="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -5.0,-5.00001525879 -5.0,-5.00001525879 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 3.58590698242,3.58601379395 3.58590698242,3.58601379395 c 0.0,0.0 7.58590698242,-7.58601379395 7.58590698242,-7.58601379395 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -9.0,9.00001525879 -9.0,9.00001525879 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1" />
     </set>
     <set android:ordering="sequentially">
         <objectAnimator
@@ -43,6 +43,6 @@
             android:propertyName="fillAlpha"
             android:valueFrom="0.0"
             android:valueTo="1.0"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_0" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_0" />
     </set>
 </set>
diff --git a/core/res/res/anim/ic_checkbox_to_checked_icon_null_animation.xml b/core/res/res/anim/btn_checkbox_to_checked_icon_null_animation.xml
similarity index 78%
rename from core/res/res/anim/ic_checkbox_to_checked_icon_null_animation.xml
rename to core/res/res/anim/btn_checkbox_to_checked_icon_null_animation.xml
index 6fa3fd5..cf2b832 100644
--- a/core/res/res/anim/ic_checkbox_to_checked_icon_null_animation.xml
+++ b/core/res/res/anim/btn_checkbox_to_checked_icon_null_animation.xml
@@ -21,13 +21,13 @@
             android:propertyName="scaleX"
             android:valueFrom="0.2"
             android:valueTo="0.18"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1" />
         <objectAnimator
             android:duration="300"
             android:propertyName="scaleX"
             android:valueFrom="0.18"
             android:valueTo="0.2"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1" />
     </set>
     <set android:ordering="sequentially">
         <objectAnimator
@@ -35,12 +35,12 @@
             android:propertyName="scaleY"
             android:valueFrom="0.2"
             android:valueTo="0.18"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1" />
         <objectAnimator
             android:duration="300"
             android:propertyName="scaleY"
             android:valueFrom="0.18"
             android:valueTo="0.2"
-            android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1" />
     </set>
 </set>
diff --git a/core/res/res/anim/ic_checkbox_to_unchecked_box_inner_merged_animation.xml b/core/res/res/anim/btn_checkbox_to_unchecked_box_inner_merged_animation.xml
similarity index 95%
rename from core/res/res/anim/ic_checkbox_to_unchecked_box_inner_merged_animation.xml
rename to core/res/res/anim/btn_checkbox_to_unchecked_box_inner_merged_animation.xml
index d35b426..97cc268 100644
--- a/core/res/res/anim/ic_checkbox_to_unchecked_box_inner_merged_animation.xml
+++ b/core/res/res/anim/btn_checkbox_to_unchecked_box_inner_merged_animation.xml
@@ -29,7 +29,7 @@
             android:valueFrom="M 0.0,-1.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
             android:valueTo="M -7.0,-7.0 l 14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1" />
     </set>
     <set android:ordering="sequentially">
         <objectAnimator
@@ -43,6 +43,6 @@
             android:propertyName="fillAlpha"
             android:valueFrom="0.0"
             android:valueTo="1.0"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_0" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_0" />
     </set>
 </set>
diff --git a/core/res/res/anim/ic_checkbox_to_unchecked_check_path_merged_animation.xml b/core/res/res/anim/btn_checkbox_to_unchecked_check_path_merged_animation.xml
similarity index 93%
rename from core/res/res/anim/ic_checkbox_to_unchecked_check_path_merged_animation.xml
rename to core/res/res/anim/btn_checkbox_to_unchecked_check_path_merged_animation.xml
index a5d814e..92ab963 100644
--- a/core/res/res/anim/ic_checkbox_to_unchecked_check_path_merged_animation.xml
+++ b/core/res/res/anim/btn_checkbox_to_unchecked_check_path_merged_animation.xml
@@ -21,7 +21,7 @@
         android:valueFrom="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -5.0,-5.00001525879 -5.0,-5.00001525879 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 3.58590698242,3.58601379395 3.58590698242,3.58601379395 c 0.0,0.0 7.58590698242,-7.58601379395 7.58590698242,-7.58601379395 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -9.0,9.00001525879 -9.0,9.00001525879 Z"
         android:valueTo="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 0.0,1.42500305176 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
         android:valueType="pathType"
-        android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+        android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1" />
     <set android:ordering="sequentially" >
         <objectAnimator
             android:duration="133"
@@ -34,6 +34,6 @@
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
             android:valueTo="0.0"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_0" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_0" />
     </set>
 </set>
diff --git a/core/res/res/anim/ic_checkbox_to_unchecked_icon_null_animation.xml b/core/res/res/anim/btn_checkbox_to_unchecked_icon_null_animation.xml
similarity index 79%
rename from core/res/res/anim/ic_checkbox_to_unchecked_icon_null_animation.xml
rename to core/res/res/anim/btn_checkbox_to_unchecked_icon_null_animation.xml
index 0f07b0e..a4c17d4 100644
--- a/core/res/res/anim/ic_checkbox_to_unchecked_icon_null_animation.xml
+++ b/core/res/res/anim/btn_checkbox_to_unchecked_icon_null_animation.xml
@@ -21,13 +21,13 @@
             android:propertyName="scaleX"
             android:valueFrom="0.2"
             android:valueTo="0.18"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1" />
         <objectAnimator
             android:duration="333"
             android:propertyName="scaleX"
             android:valueFrom="0.18"
             android:valueTo="0.2"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1" />
     </set>
     <set android:ordering="sequentially">
         <objectAnimator
@@ -35,12 +35,12 @@
             android:propertyName="scaleY"
             android:valueFrom="0.2"
             android:valueTo="0.18"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1" />
         <objectAnimator
             android:duration="333"
             android:propertyName="scaleY"
             android:valueFrom="0.18"
             android:valueTo="0.2"
-            android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+            android:interpolator="@interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1" />
     </set>
 </set>
diff --git a/core/res/res/anim/btn_radio_to_off_mtrl_dot_group_animation.xml b/core/res/res/anim/btn_radio_to_off_mtrl_dot_group_animation.xml
new file mode 100644
index 0000000..1c6efcf
--- /dev/null
+++ b/core/res/res/anim/btn_radio_to_off_mtrl_dot_group_animation.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="1.4"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleX"
+            android:valueFrom="1.4"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="scaleX"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="1.4"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleY"
+            android:valueFrom="1.4"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="scaleY"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/core/res/res/anim/btn_radio_to_off_mtrl_ring_outer_animation.xml b/core/res/res/anim/btn_radio_to_off_mtrl_ring_outer_animation.xml
new file mode 100644
index 0000000..2b5d9d3
--- /dev/null
+++ b/core/res/res/anim/btn_radio_to_off_mtrl_ring_outer_animation.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleX"
+            android:valueFrom="0.9"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/btn_radio_to_off_mtrl_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="scaleX"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/btn_radio_to_off_mtrl_animation_interpolator_0" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleY"
+            android:valueFrom="0.9"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/btn_radio_to_off_mtrl_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="scaleY"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/btn_radio_to_off_mtrl_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/core/res/res/anim/btn_radio_to_off_mtrl_ring_outer_path_animation.xml b/core/res/res/anim/btn_radio_to_off_mtrl_ring_outer_path_animation.xml
new file mode 100644
index 0000000..09be268
--- /dev/null
+++ b/core/res/res/anim/btn_radio_to_off_mtrl_ring_outer_path_animation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="strokeWidth"
+            android:valueFrom="2.0"
+            android:valueTo="2.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="strokeWidth"
+            android:valueFrom="2.0"
+            android:valueTo="18.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="strokeWidth"
+            android:valueFrom="18.0"
+            android:valueTo="2.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/core/res/res/anim/btn_radio_to_on_mtrl_dot_group_animation.xml b/core/res/res/anim/btn_radio_to_on_mtrl_dot_group_animation.xml
new file mode 100644
index 0000000..ad3a967
--- /dev/null
+++ b/core/res/res/anim/btn_radio_to_on_mtrl_dot_group_animation.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleX"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleX"
+            android:valueFrom="0.0"
+            android:valueTo="1.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="scaleX"
+            android:valueFrom="1.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleY"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleY"
+            android:valueFrom="0.0"
+            android:valueTo="1.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="scaleY"
+            android:valueFrom="1.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/core/res/res/anim/btn_radio_to_on_mtrl_ring_outer_animation.xml b/core/res/res/anim/btn_radio_to_on_mtrl_ring_outer_animation.xml
new file mode 100644
index 0000000..ef07885
--- /dev/null
+++ b/core/res/res/anim/btn_radio_to_on_mtrl_ring_outer_animation.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleX"
+            android:valueFrom="0.5"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="scaleX"
+            android:valueFrom="0.9"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="scaleY"
+            android:valueFrom="0.5"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="scaleY"
+            android:valueFrom="0.9"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/core/res/res/anim/btn_radio_to_on_mtrl_ring_outer_path_animation.xml b/core/res/res/anim/btn_radio_to_on_mtrl_ring_outer_path_animation.xml
new file mode 100644
index 0000000..642c004
--- /dev/null
+++ b/core/res/res/anim/btn_radio_to_on_mtrl_ring_outer_path_animation.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="strokeWidth"
+            android:valueFrom="2.0"
+            android:valueTo="18.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/btn_radio_to_on_mtrl_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="strokeWidth"
+            android:valueFrom="18.0"
+            android:valueTo="2.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="strokeWidth"
+            android:valueFrom="2.0"
+            android:valueTo="2.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_000.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_000.png
deleted file mode 100644
index da88e98..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_001.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_001.png
deleted file mode 100644
index 907d92d..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_002.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_002.png
deleted file mode 100644
index 9d24dc1..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_003.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_003.png
deleted file mode 100644
index 8aa2605..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_004.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_004.png
deleted file mode 100644
index b4cdf02..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_005.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_005.png
deleted file mode 100644
index 0724ed7..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_006.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_006.png
deleted file mode 100644
index c9bd4e3..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_007.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_007.png
deleted file mode 100644
index 5630ec3..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_008.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_008.png
deleted file mode 100644
index 4bf666c..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_009.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_009.png
deleted file mode 100644
index dffaa07..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_010.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_010.png
deleted file mode 100644
index 5f86e18..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_011.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_011.png
deleted file mode 100644
index 9b50aef..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_012.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_012.png
deleted file mode 100644
index 1cf5e7f..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_013.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_013.png
deleted file mode 100644
index 2bb641a..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_014.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_014.png
deleted file mode 100644
index 08e7485..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_015.png b/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_015.png
deleted file mode 100644
index 519b5a3..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_000.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_000.png
deleted file mode 100644
index 0d3e1e7..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_001.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_001.png
deleted file mode 100644
index 88c4a9e..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_002.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_002.png
deleted file mode 100644
index 8fa2e88..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_003.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_003.png
deleted file mode 100644
index 53dd9d7..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_004.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_004.png
deleted file mode 100644
index e235195..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_005.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_005.png
deleted file mode 100644
index 1721284..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_006.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_006.png
deleted file mode 100644
index 31819fa..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_007.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_007.png
deleted file mode 100644
index 5de44b9..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_008.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_008.png
deleted file mode 100644
index aa20f65..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_009.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_009.png
deleted file mode 100644
index c379ba7..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_010.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_010.png
deleted file mode 100644
index e23b410..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_011.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_011.png
deleted file mode 100644
index a9543dc..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_012.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_012.png
deleted file mode 100644
index 2473b78..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_013.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_013.png
deleted file mode 100644
index b4acc9c..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_014.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_014.png
deleted file mode 100644
index c9cf344..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_015.png b/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_015.png
deleted file mode 100644
index a8c390e..0000000
--- a/core/res/res/drawable-hdpi/btn_radio_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_000.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_000.png
deleted file mode 100644
index a2b7fce..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_001.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_001.png
deleted file mode 100644
index fe0d3b1..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_002.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_002.png
deleted file mode 100644
index d66d00d..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_003.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_003.png
deleted file mode 100644
index 2f2f5cd..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_004.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_004.png
deleted file mode 100644
index 72c9495..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_005.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_005.png
deleted file mode 100644
index 7d9090f..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_006.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_006.png
deleted file mode 100644
index c5442e8..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_007.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_007.png
deleted file mode 100644
index ca80cdb..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_008.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_008.png
deleted file mode 100644
index d41a10b..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_009.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_009.png
deleted file mode 100644
index 262c838..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_010.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_010.png
deleted file mode 100644
index 7f6ea8ba..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_011.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_011.png
deleted file mode 100644
index 8d50a81..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_012.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_012.png
deleted file mode 100644
index 0725a68..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_013.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_013.png
deleted file mode 100644
index 6191a4b..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_014.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_014.png
deleted file mode 100644
index 1904d74..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_015.png b/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_015.png
deleted file mode 100644
index bec8dda..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_000.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_000.png
deleted file mode 100644
index 54ef480..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_001.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_001.png
deleted file mode 100644
index 55c5163..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_002.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_002.png
deleted file mode 100644
index 0fe2a897..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_003.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_003.png
deleted file mode 100644
index 86efab7..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_004.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_004.png
deleted file mode 100644
index c0a5ca5..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_005.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_005.png
deleted file mode 100644
index ec55175..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_006.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_006.png
deleted file mode 100644
index 3e4a690..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_007.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_007.png
deleted file mode 100644
index da49734..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_008.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_008.png
deleted file mode 100644
index 471cda1..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_009.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_009.png
deleted file mode 100644
index d560262..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_010.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_010.png
deleted file mode 100644
index f6096b4..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_011.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_011.png
deleted file mode 100644
index 9e2500b..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_012.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_012.png
deleted file mode 100644
index efbac99..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_013.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_013.png
deleted file mode 100644
index 676f0ca..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_014.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_014.png
deleted file mode 100644
index 4803157..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_015.png b/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_015.png
deleted file mode 100644
index 4f8a162..0000000
--- a/core/res/res/drawable-mdpi/btn_radio_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_000.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_000.png
deleted file mode 100644
index b54c6ff..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_001.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_001.png
deleted file mode 100644
index fff7056..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_002.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_002.png
deleted file mode 100644
index 026462d..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_003.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_003.png
deleted file mode 100644
index 26cc8de..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_004.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_004.png
deleted file mode 100644
index c055fff..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_005.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_005.png
deleted file mode 100644
index a22e780..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_006.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_006.png
deleted file mode 100644
index 357374c..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_007.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_007.png
deleted file mode 100644
index 71d4667..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_008.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_008.png
deleted file mode 100644
index 2ed175e..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_009.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_009.png
deleted file mode 100644
index e0f7d8e..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_010.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_010.png
deleted file mode 100644
index 62b0578..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_011.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_011.png
deleted file mode 100644
index 4d6ef4a..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_012.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_012.png
deleted file mode 100644
index 37cee2d..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_013.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_013.png
deleted file mode 100644
index a8bc25f..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_014.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_014.png
deleted file mode 100644
index cf68d93..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_015.png b/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_015.png
deleted file mode 100644
index 96834bc..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_000.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_000.png
deleted file mode 100644
index d068dbe..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_001.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_001.png
deleted file mode 100644
index 4aabb1e..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_002.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_002.png
deleted file mode 100644
index bbac8e4..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_003.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_003.png
deleted file mode 100644
index 2fc7459..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_004.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_004.png
deleted file mode 100644
index 83c6d0e..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_005.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_005.png
deleted file mode 100644
index 45c08d7..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_006.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_006.png
deleted file mode 100644
index 05b7dfb..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_007.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_007.png
deleted file mode 100644
index baf9964..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_008.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_008.png
deleted file mode 100644
index d6e0369..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_009.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_009.png
deleted file mode 100644
index 3f35270..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_010.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_010.png
deleted file mode 100644
index a5b34dc..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_011.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_011.png
deleted file mode 100644
index 361967b..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_012.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_012.png
deleted file mode 100644
index c478bb7..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_013.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_013.png
deleted file mode 100644
index 075fa0c..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_014.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_014.png
deleted file mode 100644
index d9e364b..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_015.png b/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_015.png
deleted file mode 100644
index 9924496..0000000
--- a/core/res/res/drawable-xhdpi/btn_radio_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_000.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_000.png
deleted file mode 100644
index cbc3833..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_001.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_001.png
deleted file mode 100644
index 4243895..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_002.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_002.png
deleted file mode 100644
index b522d37..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_003.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_003.png
deleted file mode 100644
index 647b965..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_004.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_004.png
deleted file mode 100644
index a317497..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_005.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_005.png
deleted file mode 100644
index 0e4b25f..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_006.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_006.png
deleted file mode 100644
index 6e279d9..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_007.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_007.png
deleted file mode 100644
index f0840cc..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_008.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_008.png
deleted file mode 100644
index 140e9e8..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_009.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_009.png
deleted file mode 100644
index 5cf8ec5..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_010.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_010.png
deleted file mode 100644
index f9624d8..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_011.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_011.png
deleted file mode 100644
index 899df8c..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_012.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_012.png
deleted file mode 100644
index 6543e1c..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_013.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_013.png
deleted file mode 100644
index cd758dd..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_014.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_014.png
deleted file mode 100644
index 72d950c..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_015.png b/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_015.png
deleted file mode 100644
index 07bdbc9..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_000.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_000.png
deleted file mode 100644
index c9af24b..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_001.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_001.png
deleted file mode 100644
index 01de3f5..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_002.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_002.png
deleted file mode 100644
index f428bc5..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_003.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_003.png
deleted file mode 100644
index ab5c008..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_004.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_004.png
deleted file mode 100644
index 5b157cf..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_005.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_005.png
deleted file mode 100644
index 1210be2..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_006.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_006.png
deleted file mode 100644
index e6b4140..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_007.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_007.png
deleted file mode 100644
index b678e08..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_008.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_008.png
deleted file mode 100644
index 6ca2a69..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_009.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_009.png
deleted file mode 100644
index 7de608e..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_010.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_010.png
deleted file mode 100644
index b2bbcce..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_011.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_011.png
deleted file mode 100644
index 6950db3..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_012.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_012.png
deleted file mode 100644
index c790756..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_013.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_013.png
deleted file mode 100644
index ed5d888..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_014.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_014.png
deleted file mode 100644
index 81a4a63..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_015.png b/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_015.png
deleted file mode 100644
index db1d93a..0000000
--- a/core/res/res/drawable-xxhdpi/btn_radio_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_000.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_000.png
deleted file mode 100644
index 44028af..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_001.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_001.png
deleted file mode 100644
index ec13a86..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_002.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_002.png
deleted file mode 100644
index 43754eb..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_003.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_003.png
deleted file mode 100644
index 39d1d64..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_004.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_004.png
deleted file mode 100644
index f36f883..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_005.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_005.png
deleted file mode 100644
index 7a4cc5c..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_006.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_006.png
deleted file mode 100644
index 80a21ec..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_007.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_007.png
deleted file mode 100644
index 2141104..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_008.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_008.png
deleted file mode 100644
index 203bd51..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_009.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_009.png
deleted file mode 100644
index 5df6fc5..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_010.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_010.png
deleted file mode 100644
index 6d0fced..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_011.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_011.png
deleted file mode 100644
index 8c0c372..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_012.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_012.png
deleted file mode 100644
index 4fa6f53..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_013.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_013.png
deleted file mode 100644
index d3dbf7d..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_014.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_014.png
deleted file mode 100644
index 4ccf8de..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_015.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_015.png
deleted file mode 100644
index adef871..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_000.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_000.png
deleted file mode 100644
index adef871..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_001.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_001.png
deleted file mode 100644
index 9fc3556..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_002.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_002.png
deleted file mode 100644
index 7f00609..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_003.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_003.png
deleted file mode 100644
index e4aa58d..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_004.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_004.png
deleted file mode 100644
index fe4e4b7..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_005.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_005.png
deleted file mode 100644
index 86666ca..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_006.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_006.png
deleted file mode 100644
index 608faaf..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_007.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_007.png
deleted file mode 100644
index ec95422..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_008.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_008.png
deleted file mode 100644
index 76e2754..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_009.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_009.png
deleted file mode 100644
index 3853eac..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_010.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_010.png
deleted file mode 100644
index 621aff1..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_011.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_011.png
deleted file mode 100644
index d24be2a..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_012.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_012.png
deleted file mode 100644
index df33892..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_013.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_013.png
deleted file mode 100644
index ff4b818..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_014.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_014.png
deleted file mode 100644
index d9793ae..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_015.png b/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_015.png
deleted file mode 100644
index 44028af..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_radio_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/btn_check_material_anim.xml b/core/res/res/drawable/btn_check_material_anim.xml
index 710a291..e6752b0 100644
--- a/core/res/res/drawable/btn_check_material_anim.xml
+++ b/core/res/res/drawable/btn_check_material_anim.xml
@@ -18,16 +18,16 @@
     <item
         android:id="@+id/checked"
         android:state_checked="true"
-        android:drawable="@drawable/ic_checkbox_checked" />
+        android:drawable="@drawable/btn_checkbox_checked_mtrl" />
     <item
         android:id="@+id/unchecked"
-        android:drawable="@drawable/ic_checkbox_unchecked" />
+        android:drawable="@drawable/btn_checkbox_unchecked_mtrl" />
     <transition
         android:fromId="@+id/unchecked"
         android:toId="@+id/checked"
-        android:drawable="@drawable/ic_checkbox_unchecked_to_checked_animation" />
+        android:drawable="@drawable/btn_checkbox_unchecked_to_checked_mtrl_animation" />
     <transition
         android:fromId="@+id/checked"
         android:toId="@+id/unchecked"
-        android:drawable="@drawable/ic_checkbox_checked_to_unchecked_animation" />
+        android:drawable="@drawable/btn_checkbox_checked_to_unchecked_mtrl_animation" />
 </animated-selector>
diff --git a/core/res/res/drawable/ic_checkbox_checked.xml b/core/res/res/drawable/btn_checkbox_checked_mtrl.xml
similarity index 98%
rename from core/res/res/drawable/ic_checkbox_checked.xml
rename to core/res/res/drawable/btn_checkbox_checked_mtrl.xml
index ecde414..e2dacd5 100644
--- a/core/res/res/drawable/ic_checkbox_checked.xml
+++ b/core/res/res/drawable/btn_checkbox_checked_mtrl.xml
@@ -15,7 +15,7 @@
 -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:name="ic_checkbox_checked"
+        android:name="btn_checkbox_checked"
         android:width="32dp"
         android:viewportWidth="48"
         android:height="32dp"
diff --git a/core/res/res/drawable/ic_checkbox_checked_to_unchecked_animation.xml b/core/res/res/drawable/btn_checkbox_checked_to_unchecked_mtrl_animation.xml
similarity index 72%
rename from core/res/res/drawable/ic_checkbox_checked_to_unchecked_animation.xml
rename to core/res/res/drawable/btn_checkbox_checked_to_unchecked_mtrl_animation.xml
index fad2233..e6f9edc 100644
--- a/core/res/res/drawable/ic_checkbox_checked_to_unchecked_animation.xml
+++ b/core/res/res/drawable/btn_checkbox_checked_to_unchecked_mtrl_animation.xml
@@ -15,14 +15,14 @@
 -->
 
 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 android:drawable="@drawable/ic_checkbox_checked">
+                 android:drawable="@drawable/btn_checkbox_checked_mtrl">
     <target
         android:name="icon_null"
-        android:animation="@anim/ic_checkbox_to_unchecked_icon_null_animation" />
+        android:animation="@anim/btn_checkbox_to_unchecked_icon_null_animation" />
     <target
         android:name="check_path_merged"
-        android:animation="@anim/ic_checkbox_to_unchecked_check_path_merged_animation" />
+        android:animation="@anim/btn_checkbox_to_unchecked_check_path_merged_animation" />
     <target
         android:name="box_inner_merged"
-        android:animation="@anim/ic_checkbox_to_unchecked_box_inner_merged_animation" />
+        android:animation="@anim/btn_checkbox_to_unchecked_box_inner_merged_animation" />
 </animated-vector>
diff --git a/core/res/res/drawable/ic_checkbox_unchecked.xml b/core/res/res/drawable/btn_checkbox_unchecked_mtrl.xml
similarity index 98%
rename from core/res/res/drawable/ic_checkbox_unchecked.xml
rename to core/res/res/drawable/btn_checkbox_unchecked_mtrl.xml
index 3329b46..f4c699f 100644
--- a/core/res/res/drawable/ic_checkbox_unchecked.xml
+++ b/core/res/res/drawable/btn_checkbox_unchecked_mtrl.xml
@@ -15,7 +15,7 @@
 -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:name="ic_checkbox_unchecked"
+        android:name="btn_checkbox_unchecked"
         android:width="32dp"
         android:viewportWidth="48"
         android:height="32dp"
diff --git a/core/res/res/drawable/ic_checkbox_unchecked_to_checked_animation.xml b/core/res/res/drawable/btn_checkbox_unchecked_to_checked_mtrl_animation.xml
similarity index 73%
rename from core/res/res/drawable/ic_checkbox_unchecked_to_checked_animation.xml
rename to core/res/res/drawable/btn_checkbox_unchecked_to_checked_mtrl_animation.xml
index 68351701..e974e2b 100644
--- a/core/res/res/drawable/ic_checkbox_unchecked_to_checked_animation.xml
+++ b/core/res/res/drawable/btn_checkbox_unchecked_to_checked_mtrl_animation.xml
@@ -15,14 +15,14 @@
 -->
 
 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 android:drawable="@drawable/ic_checkbox_unchecked">
+                 android:drawable="@drawable/btn_checkbox_unchecked_mtrl">
     <target
         android:name="icon_null"
-        android:animation="@anim/ic_checkbox_to_checked_icon_null_animation" />
+        android:animation="@anim/btn_checkbox_to_checked_icon_null_animation" />
     <target
         android:name="box_outer_merged"
-        android:animation="@anim/ic_checkbox_to_checked_box_outer_merged_animation" />
+        android:animation="@anim/btn_checkbox_to_checked_box_outer_merged_animation" />
     <target
         android:name="box_inner_merged"
-        android:animation="@anim/ic_checkbox_to_checked_box_inner_merged_animation" />
+        android:animation="@anim/btn_checkbox_to_checked_box_inner_merged_animation" />
 </animated-vector>
diff --git a/core/res/res/drawable/btn_radio_material_anim.xml b/core/res/res/drawable/btn_radio_material_anim.xml
index bce579e..941f95d 100644
--- a/core/res/res/drawable/btn_radio_material_anim.xml
+++ b/core/res/res/drawable/btn_radio_material_anim.xml
@@ -15,158 +15,19 @@
 -->
 
 <animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:state_checked="true">
-        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_015"
-                android:tint="?attr/colorControlNormal"
-                android:alpha="?attr/disabledAlpha" />
-    </item>
-    <item android:state_enabled="false">
-        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_000"
-                android:tint="?attr/colorControlNormal"
-                android:alpha="?attr/disabledAlpha" />
-    </item>
-    <item android:state_checked="true" android:id="@+id/on">
-        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_015"
-                android:tint="?attr/colorControlActivated" />
-    </item>
-    <item android:id="@+id/off">
-        <bitmap android:src="@drawable/btn_radio_to_on_mtrl_000"
-                android:tint="?attr/colorControlNormal" />
-    </item>
-    <transition android:fromId="@+id/off" android:toId="@+id/on">
-        <animation-list>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_000"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_001"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_002"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_003"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_004"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_005"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_006"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_007"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_008"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_009"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_010"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_011"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_012"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_013"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_014"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_on_mtrl_015"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-        </animation-list>
-    </transition>
-    <transition android:fromId="@+id/on" android:toId="@+id/off">
-        <animation-list>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_000"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_001"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_002"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_003"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_004"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_005"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_006"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_007"
-                        android:tint="?attr/colorControlActivated" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_008"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_009"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_010"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_011"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_012"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_013"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_014"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-            <item android:duration="15">
-                <bitmap android:src="@drawable/btn_radio_to_off_mtrl_015"
-                        android:tint="?attr/colorControlNormal" />
-            </item>
-        </animation-list>
-    </transition>
+    <item
+        android:id="@+id/on"
+        android:state_checked="true"
+        android:drawable="@drawable/btn_radio_on_mtrl" />
+    <item
+        android:id="@+id/off"
+        android:drawable="@drawable/btn_radio_off_mtrl" />
+    <transition
+        android:fromId="@+id/on"
+        android:toId="@+id/off"
+        android:drawable="@drawable/btn_radio_on_to_off_mtrl_animation" />
+    <transition
+        android:fromId="@+id/off"
+        android:toId="@+id/on"
+        android:drawable="@drawable/btn_radio_off_to_on_mtrl_animation" />
 </animated-selector>
diff --git a/core/res/res/drawable/btn_radio_off_mtrl.xml b/core/res/res/drawable/btn_radio_off_mtrl.xml
new file mode 100644
index 0000000..55c7950
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_off_mtrl.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="btn_radio_to_on_mtrl"
+    android:width="32dp"
+    android:viewportWidth="32"
+    android:height="32dp"
+    android:viewportHeight="32"
+    android:tint="@color/control_checkable_material">
+    <group
+        android:name="btn_radio_to_on_mtrl_0"
+        android:translateX="16"
+        android:translateY="16" >
+        <group
+            android:name="ring_outer" >
+            <path
+                android:name="ring_outer_path"
+                android:strokeColor="#FF000000"
+                android:strokeWidth="2"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
+        </group>
+        <group
+            android:name="dot_group"
+            android:scaleX="0"
+            android:scaleY="0" >
+            <path
+                android:name="dot_path"
+                android:pathData="M 0.0,-5.0 c -2.7619934082,0.0 -5.0,2.2380065918 -5.0,5.0 c 0.0,2.7619934082 2.2380065918,5.0 5.0,5.0 c 2.7619934082,0.0 5.0,-2.2380065918 5.0,-5.0 c 0.0,-2.7619934082 -2.2380065918,-5.0 -5.0,-5.0 Z"
+                android:fillColor="#FF000000" />
+        </group>
+    </group>
+</vector>
diff --git a/core/res/res/drawable/btn_radio_off_to_on_mtrl_animation.xml b/core/res/res/drawable/btn_radio_off_to_on_mtrl_animation.xml
new file mode 100644
index 0000000..b877c04
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_off_to_on_mtrl_animation.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/btn_radio_off_mtrl" >
+    <target
+        android:name="ring_outer"
+        android:animation="@anim/btn_radio_to_on_mtrl_ring_outer_animation" />
+    <target
+        android:name="ring_outer_path"
+        android:animation="@anim/btn_radio_to_on_mtrl_ring_outer_path_animation" />
+    <target
+        android:name="dot_group"
+        android:animation="@anim/btn_radio_to_on_mtrl_dot_group_animation" />
+</animated-vector>
diff --git a/core/res/res/drawable/btn_radio_on_mtrl.xml b/core/res/res/drawable/btn_radio_on_mtrl.xml
new file mode 100644
index 0000000..ee03dbd
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_on_mtrl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="btn_radio_to_off_mtrl"
+    android:width="32dp"
+    android:viewportWidth="32"
+    android:height="32dp"
+    android:viewportHeight="32"
+    android:tint="@color/control_checkable_material">
+    <group
+        android:name="btn_radio_to_off_mtrl_0"
+        android:translateX="16"
+        android:translateY="16" >
+        <group
+            android:name="ring_outer" >
+            <path
+                android:name="ring_outer_path"
+                android:strokeColor="#FF000000"
+                android:strokeWidth="2"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
+        </group>
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot_path"
+                android:pathData="M 0.0,-5.0 c -2.7619934082,0.0 -5.0,2.2380065918 -5.0,5.0 c 0.0,2.7619934082 2.2380065918,5.0 5.0,5.0 c 2.7619934082,0.0 5.0,-2.2380065918 5.0,-5.0 c 0.0,-2.7619934082 -2.2380065918,-5.0 -5.0,-5.0 Z"
+                android:fillColor="#FF000000" />
+        </group>
+    </group>
+</vector>
diff --git a/core/res/res/drawable/btn_radio_on_to_off_mtrl_animation.xml b/core/res/res/drawable/btn_radio_on_to_off_mtrl_animation.xml
new file mode 100644
index 0000000..94ea9e3
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_on_to_off_mtrl_animation.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/btn_radio_on_mtrl" >
+    <target
+        android:name="ring_outer"
+        android:animation="@anim/btn_radio_to_off_mtrl_ring_outer_animation" />
+    <target
+        android:name="ring_outer_path"
+        android:animation="@anim/btn_radio_to_off_mtrl_ring_outer_path_animation" />
+    <target
+        android:name="dot_group"
+        android:animation="@anim/btn_radio_to_off_mtrl_dot_group_animation" />
+</animated-vector>
diff --git a/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml b/core/res/res/interpolator/btn_checkbox_checked_mtrl_animation_interpolator_0.xml
similarity index 100%
rename from core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml
rename to core/res/res/interpolator/btn_checkbox_checked_mtrl_animation_interpolator_0.xml
diff --git a/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml b/core/res/res/interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1.xml
similarity index 100%
rename from core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml
rename to core/res/res/interpolator/btn_checkbox_checked_mtrl_animation_interpolator_1.xml
diff --git a/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml b/core/res/res/interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_0.xml
similarity index 100%
copy from core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml
copy to core/res/res/interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_0.xml
diff --git a/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml b/core/res/res/interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1.xml
similarity index 100%
copy from core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml
copy to core/res/res/interpolator/btn_checkbox_unchecked_mtrl_animation_interpolator_1.xml
diff --git a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml b/core/res/res/interpolator/btn_radio_to_off_mtrl_animation_interpolator_0.xml
similarity index 85%
rename from core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml
rename to core/res/res/interpolator/btn_radio_to_off_mtrl_animation_interpolator_0.xml
index ceac663..97c9373 100644
--- a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml
+++ b/core/res/res/interpolator/btn_radio_to_off_mtrl_animation_interpolator_0.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
@@ -17,4 +16,4 @@
 
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 1.0,0.0 l 0.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.4,1.0 1.0,1.0" />
diff --git a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml b/core/res/res/interpolator/btn_radio_to_on_mtrl_animation_interpolator_0.xml
similarity index 85%
copy from core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml
copy to core/res/res/interpolator/btn_radio_to_on_mtrl_animation_interpolator_0.xml
index ceac663..97c9373 100644
--- a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml
+++ b/core/res/res/interpolator/btn_radio_to_on_mtrl_animation_interpolator_0.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
@@ -17,4 +16,4 @@
 
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 1.0,0.0 l 0.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.4,1.0 1.0,1.0" />
diff --git a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml b/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml
deleted file mode 100644
index 26bc8ad..0000000
--- a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.0,1.0 1.0,1.0" />
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index dde02d5..2d847ee 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1149,7 +1149,7 @@
     <string name="sync_really_delete" msgid="2572600103122596243">"আইটেমগুলি মুছুন"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"মোছাগুলিকে পূর্বাবস্থায় ফেরান"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"এখন কার মতো কিছু করবেন না"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"একটি অ্যাকাউন্ট নির্বাচন করুন"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"একটি অ্যাকাউন্ট বাছুন"</string>
     <string name="add_account_label" msgid="2935267344849993553">"একটি অ্যাকাউন্ট যোগ করুন"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"অ্যাকাউন্ট যোগ করুন"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"বাড়ান"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 6422355..2e3c569 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -775,7 +775,7 @@
     <string name="autofill_area" msgid="3547409050889952423">"منطقه"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"امارات"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"خواندن سابقه و نشانک‌های وب شما"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"به برنامه اجازه می‌دهد سابقه نشانی‌های اینترنتی را که مرورگر بازدید کرده است و همه نشانک‌های مرورگر را بخواند. توجه: این مجوز توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نیست."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"به برنامه اجازه می‌دهد سابقه نشانی‌های وب را که مرورگر بازدید کرده است و همه نشانک‌های مرورگر را بخواند. توجه: این مجوز توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نیست."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"نوشتن نشانک‌های وب و سابقه"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"به برنامه اجازه می‌دهد سابقه مرورگر یا نشانک‌های ذخیره شده در رایانهٔ لوحی شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد داده‌های مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نباشد."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"به برنامه اجازه می‌دهد تا سابقه یا نشانک‌های ذخیره شده مرورگر در تلویزیون شما را تغییر دهد. شاید به برنامه اجازه دهد تا داده‌های «مرورگر» را پاک کند یا تغییر دهد. توجه: این مجوز شاید توسط مرورگرهای شخص ثالث یا سایر برنامه‌ها با قابلیت‌های مرور وب اجرا شود."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 50adefa..15536cf 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1405,7 +1405,7 @@
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Code PIN actuel"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau code PIN"</string>
     <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirmer le nouveau code PIN"</string>
-    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Créer un code PIN pour modifier les restrictions"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Créer un code pour modifier les restrictions"</string>
     <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Les codes PIN ne correspondent pas. Veuillez réessayer."</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 9979d0f..7b5ca29 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -951,7 +951,7 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume dos elementos multimedia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume das notificacións"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Ton de chamada predeterminado"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de chamada predeterminado(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de chamada predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="7937634392408977062">"Ningún"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tons de chamada"</string>
     <string name="ringtone_unknown" msgid="5477919988701784788">"Ton de chamada descoñecido"</string>
diff --git a/core/res/res/values-mcc310-mnc260-nl/strings.xml b/core/res/res/values-mcc310-mnc260-nl/strings.xml
index 1c6b892..ac4961c 100644
--- a/core/res/res/values-mcc310-mnc260-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc260-nl/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Als u wilt bellen en berichten wilt verzenden via wifi, moet u eerst uw provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+    <item msgid="7239039348648848288">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreren bij uw provider"</item>
+    <item msgid="483847327467331298">"Registreren bij je provider"</item>
   </string-array>
     <string name="wfcSpnFormat" msgid="4982938551498609442">"Bellen via wifi van %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc730-mnc01/config.xml b/core/res/res/values-mcc730-mnc01/config.xml
new file mode 100644
index 0000000..22f4027
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc01/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>73010</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc730-mnc07/config.xml b/core/res/res/values-mcc730-mnc07/config.xml
new file mode 100644
index 0000000..836ddf9
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc07/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>73002</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc730-mnc08/config.xml b/core/res/res/values-mcc730-mnc08/config.xml
new file mode 100644
index 0000000..836ddf9
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc08/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>73002</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc730-mnc10/config.xml b/core/res/res/values-mcc730-mnc10/config.xml
new file mode 100644
index 0000000..58b7d78
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc10/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>73001</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-nl-watch/strings.xml b/core/res/res/values-nl-watch/strings.xml
index 590d146..967cf90 100644
--- a/core/res/res/values-nl-watch/strings.xml
+++ b/core/res/res/values-nl-watch/strings.xml
@@ -22,15 +22,15 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="android_upgrading_apk" msgid="1090732262010398759">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="202675452368612754">"Sensoren"</string>
-    <string name="permgrouplab_contactswear" msgid="2340286500790908344">"toegang tot uw contacten"</string>
+    <string name="permgrouplab_contactswear" msgid="2340286500790908344">"toegang tot je contacten"</string>
     <string name="permgrouplab_locationwear" msgid="6275317222482780209">"toegang tot de locatie van dit horloge"</string>
-    <string name="permgrouplab_calendarwear" msgid="441900844045065081">"toegang tot uw agenda"</string>
+    <string name="permgrouplab_calendarwear" msgid="441900844045065081">"toegang tot je agenda"</string>
     <string name="permgrouplab_smswear" msgid="6849506550342974220">"sms\'jes verzenden en bekijken"</string>
-    <string name="permgrouplab_storagewear" msgid="1003807594193602313">"toegang tot foto\'s, media en bestanden op uw horloge"</string>
+    <string name="permgrouplab_storagewear" msgid="1003807594193602313">"toegang tot foto\'s, media en bestanden op je horloge"</string>
     <string name="permgrouplab_microphonewear" msgid="1047561180980891136">"audio opnemen"</string>
     <string name="permgrouplab_camerawear" msgid="4543951283103407017">"foto\'s maken en video opnemen"</string>
     <string name="permgrouplab_phonewear" msgid="134365036753766126">"bellen en telefoontjes beheren"</string>
-    <string name="permgrouplab_sensorswear" msgid="1429324744329327663">"toegang tot sensorgegevens over uw vitale functies"</string>
+    <string name="permgrouplab_sensorswear" msgid="1429324744329327663">"toegang tot sensorgegevens over je vitale functies"</string>
     <string name="permlab_statusBarServicewear" msgid="2469402818964691034">"de statusbalk zijn"</string>
     <string name="permlab_bodySensorswear" msgid="7857941041202791873">"toegang tot lichaamssensoren (zoals hartslagmeters)"</string>
     <string name="permlab_accessFineLocationwear" msgid="5584423486924377563">"toegang tot precieze locatie (GPS- en netwerkgebaseerd)"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index d77dca1f..a850943 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -53,17 +53,17 @@
     <string name="serviceErased" msgid="1288584695297200972">"Wissen uitgevoerd."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"Onjuist wachtwoord."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI voltooid."</string>
-    <string name="badPin" msgid="9015277645546710014">"De oude pincode die u heeft ingevoerd, is onjuist."</string>
-    <string name="badPuk" msgid="5487257647081132201">"De PUK-code die u heeft ingevoerd, is onjuist."</string>
-    <string name="mismatchPin" msgid="609379054496863419">"De pincodes die u heeft ingevoerd, komen niet overeen."</string>
+    <string name="badPin" msgid="9015277645546710014">"De oude pincode die je hebt ingevoerd, is onjuist."</string>
+    <string name="badPuk" msgid="5487257647081132201">"De PUK-code die je hebt ingevoerd, is onjuist."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"De pincodes die je hebt ingevoerd, komen niet overeen."</string>
     <string name="invalidPin" msgid="3850018445187475377">"Voer een pincode van 4 tot 8 cijfers in."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"Typ een PUK-code die 8 cijfers of langer is."</string>
-    <string name="needPuk" msgid="919668385956251611">"Uw SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
+    <string name="needPuk" msgid="919668385956251611">"Je SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Voer de PUK2-code in om de SIM-kaart te ontgrendelen."</string>
     <string name="enablePin" msgid="209412020907207950">"Mislukt. Schakel SIM/RUIM-vergrendeling in."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="other">U heeft nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart wordt vergrendeld.</item>
-      <item quantity="one">U heeft nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart wordt vergrendeld.</item>
+      <item quantity="other">Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart wordt vergrendeld.</item>
+      <item quantity="one">Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart wordt vergrendeld.</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -167,14 +167,14 @@
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefoongeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan worden gecontroleerd"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Door een onbekende derde partij"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Door uw werkprofielbeheerder"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Door je werkprofielbeheerder"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Door <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Werkprofiel verwijderd"</string>
     <string name="work_profile_deleted_description" msgid="6305147513054341102">"Werkprofiel verwijderd wegens ontbrekende beheerapp."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"De beheerapp van het werkprofiel ontbreekt of is beschadigd. Als gevolg hiervan zijn uw werkprofiel en alle gerelateerde gegevens verwijderd. Neem voor hulp contact op met uw beheerder."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Uw werkprofiel is niet meer beschikbaar op dit apparaat."</string>
-    <string name="factory_reset_warning" msgid="5423253125642394387">"Uw apparaat wordt gewist"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Er ontbreken onderdelen van de beheerapp of de app is beschadigd, waardoor de app niet kan worden gebruikt. Uw apparaat wordt nu gewist. Neem voor hulp contact op met uw beheerder."</string>
+    <string name="work_profile_deleted_details" msgid="226615743462361248">"De beheerapp van het werkprofiel ontbreekt of is beschadigd. Als gevolg hiervan zijn je werkprofiel en alle gerelateerde gegevens verwijderd. Neem voor hulp contact op met je beheerder."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Je werkprofiel is niet meer beschikbaar op dit apparaat."</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"Je apparaat wordt gewist"</string>
+    <string name="factory_reset_message" msgid="4905025204141900666">"Er ontbreken onderdelen van de beheerapp of de app is beschadigd, waardoor de app niet kan worden gebruikt. Je apparaat wordt nu gewist. Neem voor hulp contact op met je beheerder."</string>
     <string name="me" msgid="6545696007631404292">"Ik"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tabletopties"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV-opties"</string>
@@ -194,10 +194,10 @@
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"Terugzetten op fabrieksinstellingen"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Opnieuw opstarten…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Uitschakelen..."</string>
-    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Uw tablet wordt uitgeschakeld."</string>
-    <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Uw tv wordt uitgeschakeld.."</string>
-    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Uw horloge wordt uitgeschakeld."</string>
-    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Uw telefoon wordt uitgeschakeld."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Je tablet wordt uitgeschakeld."</string>
+    <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Je tv wordt uitgeschakeld.."</string>
+    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Je horloge wordt uitgeschakeld."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Je telefoon wordt uitgeschakeld."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Wilt u afsluiten?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"Opnieuw opstarten in veilige modus"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"Wilt u opnieuw opstarten in de veilige modus? Als u dit doet, worden alle geïnstalleerde applicaties van derden uitgeschakeld. Ze worden weer ingeschakeld als u weer opnieuw opstart."</string>
@@ -210,7 +210,7 @@
     <string name="global_action_power_off" msgid="4471879440839879722">"Uitschakelen"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Foutenrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Foutenrapport genereren"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van uw apparaat verzameld en als e-mail verzonden. Wanneer u een foutenrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een foutenrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stille modus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Geluid is UIT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Geluid is AAN"</string>
@@ -227,15 +227,15 @@
     <string name="user_owner_label" msgid="2804351898001038951">"Persoonlijk"</string>
     <string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacten"</string>
-    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot uw contacten"</string>
+    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot je contacten"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Locatie"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"de locatie van dit apparaat openen"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
-    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot uw agenda"</string>
+    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot je agenda"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"sms\'jes verzenden en bekijken"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Opslagruimte"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"toegang krijgen tot foto\'s, media en bestanden op uw apparaat"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"toegang krijgen tot foto\'s, media en bestanden op je apparaat"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfoon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"audio opnemen"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
@@ -243,9 +243,9 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoon"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"bellen en telefoontjes beheren"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Lichaamssensoren"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang tot sensorgegevens over uw vitale functies"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang tot sensorgegevens over je vitale functies"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Inhoud van vensters ophalen"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee u interactie heeft."</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee je interactie hebt."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'Verkennen via aanraking\' inschakelen"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Aangeraakte items worden hardop benoemd en het scherm kan worden verkend door middel van aanraking."</string>
     <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Verbeterde internettoegankelijkheid inschakelen"</string>
@@ -265,33 +265,33 @@
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"uitgaande oproepen doorschakelen"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"De app toestaan het nummer te bekijken dat wordt gekozen voor een uitgaande oproep, met de mogelijkheid de oproep om te leiden naar een ander nummer of de oproep helemaal af te breken."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"tekstberichten (SMS) ontvangen"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"tekstberichten (MMS) ontvangen"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"infodienstberichten lezen"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op uw apparaat. Infodienstberichten worden verzonden naar bepaalde locaties om u te waarschuwen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van uw apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op je apparaat. Infodienstberichten worden verzonden naar bepaalde locaties om u te waarschjeen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van je apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Geabonneerde feeds lezen"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Hiermee kan de app details over de huidige gesynchroniseerde feeds achterhalen."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"sms\'jes verzenden en bekijken"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"Hiermee kan de app sms-berichten verzenden. Dit kan tot onverwachte kosten leiden. Schadelijke apps kunnen u geld kosten doordat ze zonder uw bevestiging berichten kunnen verzenden."</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"uw tekstberichten (SMS of MMS) lezen"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op uw tablet of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
-    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op uw tv of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op uw telefoon of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Hiermee kan de app sms-berichten verzenden. Dit kan tot onverwachte kosten leiden. Schadelijke apps kunnen u geld kosten doordat ze zonder je bevestiging berichten kunnen verzenden."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"je tekstberichten (SMS of MMS) lezen"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op je tablet of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op je tv of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op je telefoon of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"tekstberichten (WAP) ontvangen"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"actieve apps ophalen"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Hiermee kan de app informatie ophalen over actieve en recent uitgevoerde taken. Zo kan de app informatie vinden over welke apps op het apparaat worden gebruikt."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profiel- en apparaateigenaren beheren"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Apps toestaan de profieleigenaren en apparaateigenaar in te stellen."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"actieve apps opnieuw rangschikken"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. De app kan dit doen zonder om uw bevestiging te vragen."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. De app kan dit doen zonder om je bevestiging te vragen."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"automodus inschakelen"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Hiermee kan de app de automodus inschakelen."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"andere apps sluiten"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Hiermee kan de app achtergrondprocessen van andere apps beëindigen. Hierdoor kunnen andere apps worden gestopt."</string>
     <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"Weergeven over andere apps"</string>
-    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Hiermee kan de app tekenen op andere apps of de gebruikersinterface. De app kan uw gebruik van de interface in alle apps verstoren, of wijzigen wat u in andere apps denkt te zien."</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Hiermee kan de app tekenen op andere apps of de gebruikersinterface. De app kan je gebruik van de interface in alle apps verstoren, of wijzigen wat u in andere apps denkt te zien."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"app altijd laten uitvoeren"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Hiermee kan de app gedeelten van zichzelf persistent maken in het geheugen. Dit kan de hoeveelheid geheugen beperken die beschikbaar is voor andere apps, waardoor de tablet trager kan worden."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Hiermee kan de app gedeelten van zichzelf persistent maken in het geheugen. Dit kan de hoeveelheid geheugen beperken die beschikbaar is voor andere apps, waardoor de tv trager kan worden."</string>
@@ -299,7 +299,7 @@
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"opslagruimte van app meten"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Hiermee kan de app de bijbehorende code, gegevens en cachegrootten ophalen."</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"systeeminstellingen aanpassen"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Hiermee kan de app de instellingsgegevens van het systeem aanpassen. Schadelijke apps kunnen de configuratie van uw systeem verstoren."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Hiermee kan de app de instellingsgegevens van het systeem aanpassen. Schadelijke apps kunnen de configuratie van je systeem verstoren."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"uitvoeren bij opstarten"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Hiermee kan de app zichzelf laten starten zodra het systeem is opgestart. Hierdoor kan het langer duren voordat de tablet is opgestart en een app kan altijd actief zijn, wat de tablet kan vertragen."</string>
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Hiermee kan de app zichzelf laten starten zodra het systeem is opgestart. Hierdoor kan het langer duren voordat de tv is opgestart en een app kan altijd actief zijn, wat de tablet kan vertragen."</string>
@@ -308,54 +308,54 @@
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Hiermee kan de app sticky broadcasts verzenden die behouden blijven nadat de broadcast is beëindigd. Bij overmatig gebruik kan de tablet traag of instabiel worden omdat er te veel geheugenruimte wordt gebruikt."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Hiermee kan de app sticky broadcasts verzenden die achterblijven nadat de uitzending is afgelopen. Overmatig gebruik kan de tv traag instabiel maken doordat er te veel geheugen wordt gebruikt."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Hiermee kan de app sticky broadcasts verzenden die behouden blijven nadat de broadcast is beëindigd. Bij overmatig gebruik kan de telefoon traag of instabiel worden omdat er te veel geheugenruimte wordt gebruikt."</string>
-    <string name="permlab_readContacts" msgid="8348481131899886131">"uw contacten lezen"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op uw tablet, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps uw contactgegevens opslaan, en schadelijke apps kunnen zonder uw medeweten contactgegevens delen."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op uw tv, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps uw contactgegevens opslaan, en schadelijke apps kunnen zonder uw medeweten contactgegevens delen."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op uw telefoon, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps uw contactgegevens opslaan, en schadelijke apps kunnen zonder uw medeweten contactgegevens delen."</string>
-    <string name="permlab_writeContacts" msgid="5107492086416793544">"uw contacten aanpassen"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw tablet, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw tv, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw telefoon, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"je contacten lezen"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je tablet, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je tv, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je telefoon, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"je contacten aanpassen"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je tablet, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je tv, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je telefoon, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"gesprekkenlijst lezen"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Hiermee kan de app het gesprekkenlijst van uw tablet lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
-    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Hiermee kan de app het gesprekkenlijst van uw tv lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen oproeploggegevens zonder uw medeweten delen."</string>
-    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Hiermee kan de app het gesprekkenlijst van uw telefoon lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Hiermee kan de app het gesprekkenlijst van je tablet lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps je oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder je medeweten delen."</string>
+    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Hiermee kan de app het gesprekkenlijst van je tv lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps je oproeploggegevens opslaan, en schadelijke apps kunnen oproeploggegevens zonder je medeweten delen."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Hiermee kan de app het gesprekkenlijst van je telefoon lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps je oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder je medeweten delen."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"gesprekkenlijst schrijven"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het gesprekkenlijst van uw tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Toestaan dat de app het gesprekkenlijst van uw tv aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het gesprekkenlijst van uw telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het gesprekkenlijst van je tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee je gesprekkenlijst wissen of aanpassen."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Toestaan dat de app het gesprekkenlijst van je tv aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee je gesprekkenlijst wissen of aanpassen."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het gesprekkenlijst van je telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee je gesprekkenlijst wissen of aanpassen."</string>
     <string name="permlab_bodySensors" msgid="4871091374767171066">"lichaamssensoren (zoals hartslagmeters)"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Hiermee kan de app toegang krijgen tot gegevens van sensoren die uw lichamelijke conditie controleren, zoals uw hartslag."</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Hiermee kan de app toegang krijgen tot gegevens van sensoren die je lichamelijke conditie controleren, zoals je hartslag."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"agenda-afspraken en vertrouwelijke informatie lezen"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw tablet, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw tv, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw telefoon, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op je tablet, inclusief die van vrienden of collega\'s. De app kan je agenda delen of je agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op je tv, inclusief die van vrienden of collega\'s. De app kan je agenda delen of je agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op je telefoon, inclusief die van vrienden of collega\'s. De app kan je agenda delen of je agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"agenda-afspraken toevoegen of wijzigen en e-mails verzenden aan gasten zonder medeweten van de eigenaren"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op uw tablet, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op uw tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op uw telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op je tablet, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op je tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op je telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"toegang tot extra opdrachten van locatieaanbieder"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van GPS of andere locatiebronnen te verstoren."</string>
     <string name="permlab_accessFineLocation" msgid="1191898061965273372">"precieze locatie (GPS- en netwerkgebaseerd)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app uw precieze locatie bepalen via GPS (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op uw apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app je precieze locatie bepalen via GPS (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string>
     <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"geschatte locatie (netwerkgebaseerd)"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Hiermee kan de app beschikken over uw geschatte locatie. Deze locatie wordt afgeleid van locatieservices die netwerklocatiebronnen zoals zendmasten en wifi gebruiken. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op uw apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om ongeveer te bepalen waar u zich bevindt."</string>
-    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"uw audio-instellingen wijzigen"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Hiermee kan de app beschikken over je geschatte locatie. Deze locatie wordt afgeleid van locatieservices die netwerklocatiebronnen zoals zendmasten en wifi gebruiken. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om ongeveer te bepalen waar u zich bevindt."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"je audio-instellingen wijzigen"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Hiermee kan de app algemene audio-instellingen wijzigen zoals het volume en welke luidspreker wordt gebruikt voor de uitvoer."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"audio opnemen"</string>
-    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Hiermee kan de app audio opnemen met de microfoon. Met deze toestemming kan de app op elk moment audio opnemen, zonder om uw bevestiging te vragen."</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Hiermee kan de app audio opnemen met de microfoon. Met deze toestemming kan de app op elk moment audio opnemen, zonder om je bevestiging te vragen."</string>
     <string name="permlab_sim_communication" msgid="1180265879464893029">"sim-communicatie"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Hiermee kan de app opdrachten verzenden naar de simkaart. Dit is erg gevaarlijk."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"foto\'s en video\'s maken"</string>
-    <string name="permdesc_camera" msgid="8497216524735535009">"Hiermee kan de app foto\'s en video\'s maken met de camera. Met deze toestemming kan de app de camera altijd gebruiken, zonder uw bevestiging."</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Hiermee kan de app foto\'s en video\'s maken met de camera. Met deze toestemming kan de app de camera altijd gebruiken, zonder je bevestiging."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"trilling beheren"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Hiermee kan de app de trilstand beheren."</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"zaklamp bedienen"</string>
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Hiermee kan de app de zaklamp bedienen."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"telefoonnummers rechtstreeks bellen"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"Hiermee kan de app zonder uw tussenkomst telefoonnummers bellen. Dit kan tot onverwachte kosten of oproepen leiden. De app kan hiermee geen noodnummers bellen. Schadelijke apps kunnen u geld kosten door nummers te bellen zonder om uw bevestiging te vragen."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Hiermee kan de app zonder je tussenkomst telefoonnummers bellen. Dit kan tot onverwachte kosten of oproepen leiden. De app kan hiermee geen noodnummers bellen. Schadelijke apps kunnen u geld kosten door nummers te bellen zonder om je bevestiging te vragen."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"toegang tot IMS-service voor bellen"</string>
-    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Hiermee kan de app de IMS-service gebruiken om te bellen zonder uw tussenkomst."</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Hiermee kan de app de IMS-service gebruiken om te bellen zonder je tussenkomst."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefoonstatus en -identiteit lezen"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Hiermee kan de app toegang krijgen tot de telefoonfuncties van het apparaat, Met deze toestemming kan de app het telefoonnummer en de apparaat-ID\'s bepalen, of een oproep actief is, en het andere telefoonnummer waarmee wordt gebeld."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"voorkomen dat tablet overschakelt naar slaapmodus"</string>
@@ -370,16 +370,16 @@
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Hiermee kan de app de infraroodzender van de telefoon gebruiken."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"achtergrond instellen"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Hiermee kan de app de systeemachtergrond instellen."</string>
-    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"uw achtergrondformaat aanpassen"</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"je achtergrondformaat aanpassen"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Hiermee kan de app de grootte van de achtergrond instellen."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"tijdzone instellen"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Hiermee kan de app de tijdzone van de tablet wijzigen."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Hiermee kan de app de tijdzone van de tv wijzigen."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Hiermee kan de app de tijdzone van de telefoon wijzigen."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"accounts op het apparaat vinden"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tablet bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die u heeft geïnstalleerd."</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tv bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die u heeft geïnstalleerd."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Hiermee krijgt de app toegang tot de lijst met accounts die op de telefoon bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die u heeft geïnstalleerd."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tablet bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tv bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Hiermee krijgt de app toegang tot de lijst met accounts die op de telefoon bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"netwerkverbindingen weergeven"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Hiermee kan de app informatie bekijken over netwerkverbindingen, zoals welke netwerken er zijn en welke verbonden zijn."</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"volledige netwerktoegang"</string>
@@ -393,9 +393,9 @@
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wifi-verbinding maken en verbreken"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Hiermee kan de app zich koppelen aan en ontkoppelen van wifi-toegangspunten en wijzigingen aanbrengen in de apparaatconfiguratie voor wifi-netwerken."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wifi Multicast-ontvangst toestaan"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar uw tablet. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Hiermee kan de app pakketten ontvangen die zijn verzonden naar alle apparaten op een Wi-Fi-netwerk met multicastadressen en niet alleen uw tv. Er wordt meer stroom verbruikt dan in de niet-multicastmodus."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar uw telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je tablet. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Hiermee kan de app pakketten ontvangen die zijn verzonden naar alle apparaten op een Wi-Fi-netwerk met multicastadressen en niet alleen je tv. Er wordt meer stroom verbruikt dan in de niet-multicastmodus."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth-instellingen openen"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Hiermee kan de app de lokale Bluetooth-tablet configureren en externe apparaten zoeken en koppelen."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Hiermee kan de app de configuratie van de lokale Bluetooth-tv weergeven en externe apparaten zoeken en een koppeling maken."</string>
@@ -412,7 +412,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Hiermee kan de app de Bluetooth-configuratie van de telefoon bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication regelen"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Hiermee kan de app communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"uw schermvergrendeling uitschakelen"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"je schermvergrendeling uitschakelen"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Hiermee kan de app de toetsenblokkering en bijbehorende wachtwoordbeveiliging uitschakelen. Zo kan de telefoon de toetsenblokkering uitschakelen wanneer er een oproep binnenkomt en de toetsenblokkering weer inschakelen als de oproep is beëindigd."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Vingerafdrukhardware beheren"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Hiermee kan de app methoden aanroepen om vingerafdruksjablonen toe te voegen en te verwijderen voor gebruik."</string>
@@ -441,12 +441,12 @@
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Hiermee kan een app de synchronisatie-instellingen aanpassen voor een account. Deze toestemming kan bijvoorbeeld worden gebruikt om synchronisatie van de app Personen in te schakelen voor een account."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"synchronisatiestatistieken lezen"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Hiermee kan een app de synchronisatiestatistieken voor een account lezen, inclusief de geschiedenis van synchronisatie-activiteiten en hoeveel gegevens zijn gesynchroniseerd."</string>
-    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"de inhoud van uw USB-opslag lezen"</string>
-    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"de inhoud van uw SD-kaart lezen"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"De app toestaan de inhoud van uw USB-opslag te lezen."</string>
-    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"De app toestaan de inhoud van uw SD-kaart te lezen."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"de inhoud van uw USB-opslag aanpassen of verwijderen"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"de inhoud van uw SD-kaart aanpassen of verwijderen"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"de inhoud van je USB-opslag lezen"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"de inhoud van je SD-kaart lezen"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"De app toestaan de inhoud van je USB-opslag te lezen."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"De app toestaan de inhoud van je SD-kaart te lezen."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"de inhoud van je USB-opslag aanpassen of verwijderen"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"de inhoud van je SD-kaart aanpassen of verwijderen"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Hiermee kan de app schrijven naar de USB-opslag."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Hiermee kan de app schrijven naar de SD-kaart."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP-oproepen plaatsen/ontvangen"</string>
@@ -668,7 +668,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Plaats een simkaart."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Onbruikbare simkaart."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Uw simkaart is permanent uitgeschakeld.\n Neem contact op met uw mobiele serviceprovider voor een nieuwe simkaart."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Je simkaart is permanent uitgeschakeld.\n Neem contact op met je mobiele serviceprovider voor een nieuwe simkaart."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Vorig nummer"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Volgend nummer"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Onderbreken"</string>
@@ -682,28 +682,28 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Raadpleeg de gebruikershandleiding of neem contact op met de klantenservice."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is vergrendeld."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaart ontgrendelen..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen met uw aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt u gevraagd uw tv te ontgrendelen met uw inloggegevens voor Google.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen met uw aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"U heeft op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"U heeft op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met je inloggegevens voor Google.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Je hebt nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Je hebt op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Patroon vergeten?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account ontgrendelen"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Te veel patroonpogingen"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Log in op uw Google-account om te ontgrendelen."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Log in op je Google-account om te ontgrendelen."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Gebruikersnaam (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Wachtwoord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inloggen"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Gebruikersnaam of wachtwoord ongeldig."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"https://www.google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bent u je gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"https://www.google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Controleren…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontgrendelen"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Geluid aan"</string>
@@ -774,23 +774,23 @@
     <string name="autofill_parish" msgid="8202206105468820057">"Gemeente"</string>
     <string name="autofill_area" msgid="3547409050889952423">"Gebied"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emiraat"</string>
-    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"uw webbladwijzers en -geschiedenis lezen"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"je webbladwijzers en -geschiedenis lezen"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Hiermee kan de app de geschiedenis lezen van alle URL\'s die in de systeemeigen browser zijn bezocht, en alle bladwijzers in de systeemeigen browser. Let op: deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"webbladwijzers en -geschiedenis schrijven"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw tablet. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden.."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw tv. De app kan browsergegevens wissen of aanpassen. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw telefoon. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op je tablet. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden.."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op je tv. De app kan browsergegevens wissen of aanpassen. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op je telefoon. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"een alarm instellen"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Hiermee kan de app een alarm instellen in een geïnstalleerde wekkerapp. Deze functie wordt door sommige wekkerapps niet geïmplementeerd."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"voicemail toevoegen"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van uw voicemail."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van je voicemail."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"geolocatiemachtigingen voor browser aanpassen"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Hiermee kan de app de geolocatiemachtigingen van de browser aanpassen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
     <string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Niet nu"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Onthouden"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Nooit"</string>
-    <string name="open_permission_deny" msgid="7374036708316629800">"U heeft geen toestemming om deze pagina te openen."</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Je hebt geen toestemming om deze pagina te openen."</string>
     <string name="text_copied" msgid="4985729524670131385">"Tekst naar klembord gekopieerd."</string>
     <string name="more_item_label" msgid="4650918923083320495">"Meer"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
@@ -805,8 +805,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Zoekopdracht verzenden"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Gesproken zoekopdrachten"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\'Verkennen via aanraking\' aan?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder je vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder je vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 maand geleden"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Meer dan 1 maand geleden"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -868,7 +868,7 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Onvoldoende opslagruimte voor het systeem. Zorg ervoor dat u 250 MB vrije ruimte heeft en start opnieuw."</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Onvoldoende opslagruimte voor het systeem. Zorg ervoor dat je 250 MB vrije ruimte hebt en start opnieuw."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> wordt uitgevoerd"</string>
     <string name="app_running_notification_text" msgid="4653586947747330058">"Raak aan voor meer informatie of om de app te stoppen."</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
@@ -996,8 +996,8 @@
     <string name="sms_control_yes" msgid="3663725993855816807">"Toestaan"</string>
     <string name="sms_control_no" msgid="625438561395534982">"Weigeren"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wil graag een bericht verzenden naar &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
-    <string name="sms_short_code_details" msgid="5873295990846059400">"Hiervoor "<b>"worden mogelijk kosten in rekening gebracht"</b>" op uw mobiele account."</string>
-    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Hiervoor worden kosten in rekening gebracht op uw mobiele account."</b></string>
+    <string name="sms_short_code_details" msgid="5873295990846059400">"Hiervoor "<b>"worden mogelijk kosten in rekening gebracht"</b>" op je mobiele account."</string>
+    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Hiervoor worden kosten in rekening gebracht op je mobiele account."</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Verzenden"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Annuleren"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Mijn keuze onthouden"</string>
@@ -1008,7 +1008,7 @@
     <string name="sim_removed_message" msgid="5450336489923274918">"Het mobiele netwerk is pas beschikbaar zodra u het apparaat opnieuw start met een geldige simkaart."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Gereed"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"Simkaart aangesloten"</string>
-    <string name="sim_added_message" msgid="7797975656153714319">"Start uw apparaat opnieuw voor toegang tot het mobiele netwerk."</string>
+    <string name="sim_added_message" msgid="7797975656153714319">"Start je apparaat opnieuw voor toegang tot het mobiele netwerk."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Opnieuw starten"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Tijd instellen"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
@@ -1090,15 +1090,15 @@
     <string name="ime_action_default" msgid="2840921885558045721">"Uitvoeren"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Contact maken\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot uw account, nu en in de toekomst."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot je account, nu en in de toekomst."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wilt u dit verzoek toestaan?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Verzoek om toegang"</string>
     <string name="allow" msgid="7225948811296386551">"Toestaan"</string>
     <string name="deny" msgid="2081879885755434506">"Weigeren"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Toestemming gevraagd"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Toestemming gevraagd\nvoor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
-    <string name="forward_intent_to_owner" msgid="1207197447013960896">"U gebruikt deze app buiten uw werkprofiel"</string>
-    <string name="forward_intent_to_work" msgid="621480743856004612">"U gebruikt deze app in uw werkprofiel"</string>
+    <string name="forward_intent_to_owner" msgid="1207197447013960896">"U gebruikt deze app buiten je werkprofiel"</string>
+    <string name="forward_intent_to_work" msgid="621480743856004612">"U gebruikt deze app in je werkprofiel"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Invoermethode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchroniseren"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Toegankelijkheid"</string>
@@ -1264,7 +1264,7 @@
     <string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Onjuiste pincode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%1$d</xliff:g> seconden opnieuw."</string>
-    <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken uw patroon"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken je patroon"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Geef de pincode van de simkaart op"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Pincode opgeven"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"Wachtwoord invoeren"</string>
@@ -1278,28 +1278,28 @@
     <string name="kg_invalid_puk" msgid="3638289409676051243">"Geef de juiste PUK-code opnieuw op. Bij herhaalde pogingen wordt de simkaart permanent uitgeschakeld."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pincodes komen niet overeen"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogingen"</string>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"Als u wilt ontgrendelen, moet u inloggen op uw Google-account."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Als u wilt ontgrendelen, moet u inloggen op je Google-account."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"Gebruikersnaam (e-mail)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Wachtwoord"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Inloggen"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikersnaam of wachtwoord."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u je gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Account controleren…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"U heeft op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"U heeft op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt u gevraagd uw tv te ontgrendelen met een e-mailaccount.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Je hebt nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Je hebt op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met een e-mailaccount.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls u langere tijd op hoog volume naar muziek luistert, raakt uw gehoor mogelijk beschadigd."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls u langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Toegankelijkheid ingeschakeld."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string>
@@ -1307,7 +1307,7 @@
     <string name="user_switching_message" msgid="2871009331809089783">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigenaar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Deze wijziging is niet toegestaan door uw beheerder"</string>
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Deze wijziging is niet toegestaan door je beheerder"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Er is geen app gevonden om deze actie uit te voeren"</string>
     <string name="revoke" msgid="5404479185228271586">"Intrekken"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1433,10 +1433,10 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vraag pin voor losmaken"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vraag patroon voor losmaken"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vraag wachtwoord voor losmaken"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Geïnstalleerd door uw beheerder"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Geüpdatet door uw beheerder"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door uw beheerder"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Accubesparing beperkt de prestaties van uw apparaat, de trilstand, locatieservices en de meeste achtergrondgegevens om de gebruiksduur van de accu te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld terwijl uw apparaat wordt opgeladen."</string>
+    <string name="package_installed_device_owner" msgid="8420696545959087545">"Geïnstalleerd door je beheerder"</string>
+    <string name="package_updated_device_owner" msgid="8856631322440187071">"Geüpdatet door je beheerder"</string>
+    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door je beheerder"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Accubesparing beperkt de prestaties van je apparaat, de trilstand, locatieservices en de meeste achtergrondgegevens om de gebruiksduur van de accu te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld terwijl je apparaat wordt opgeladen."</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d minuten (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Eén minuut (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
@@ -1480,8 +1480,8 @@
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evenement"</string>
     <string name="muted_by" msgid="6147073845094180001">"Gedempt door <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"Er is een intern probleem met uw apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
-    <string name="system_error_manufacturer" msgid="8086872414744210668">"Er is een intern probleem met uw apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Er is een intern probleem met je apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Er is een intern probleem met je apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD-verzoek is gewijzigd in DIAL-verzoek."</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD-verzoek is gewijzigd in SS-verzoek."</string>
     <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD-verzoek is gewijzigd in nieuw USSD-verzoek."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 82d1c02..0ef89a6 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -69,8 +69,8 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"Nazwa rozmówcy przy połączeniach przychodzących"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"Nazwa rozmówcy przy połączeniach wychodzących"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"ID rozmówcy przy połączeniach przychodzących"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"ID rozmówcy przy połączeniach wychodzących"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"Identyfikator połączonej linii"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"Ograniczenie identyfikatora połączonej linii"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Przekierowanie połączeń"</string>
@@ -84,12 +84,12 @@
     <string name="RuacMmi" msgid="7827887459138308886">"Odrzucanie niepożądanych, irytujących połączeń"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Dostarczanie numeru telefonującego"</string>
     <string name="DndMmi" msgid="1265478932418334331">"Nie przeszkadzać"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Nazwa rozmówcy ustawiona jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Nazwa rozmówcy ustawiona jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Nazwa rozmówcy ustawiona jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Nazwa rozmówcy ustawiona jest domyślnie na „nie zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ID rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Usługa nie jest świadczona."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"Nie możesz zmienić ustawienia identyfikatora rozmówcy."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Nie możesz zmienić ustawienia ID rozmówcy."</string>
     <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Zmieniono ograniczenie dostępu"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"Usługa transmisji danych jest zablokowana."</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Usługa połączeń alarmowych jest zablokowana."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 59d1a7c..48bfe28 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1820,6 +1820,7 @@
         <enum name="KEYCODE_MEDIA_SKIP_BACKWARD" value="273" />
         <enum name="KEYCODE_MEDIA_STEP_FORWARD" value="274" />
         <enum name="KEYCODE_MEDIA_STEP_BACKWARD" value="275" />
+        <enum name="KEYCODE_SOFT_SLEEP" value="276" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
index c66fd15..922bc59 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
@@ -11,6 +11,7 @@
 
 public class AnimatorSetActivityTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
 
+    private static final long POLL_INTERVAL = 100; // ms
     private AnimatorSetActivity mActivity;
     private ObjectAnimator a1,a2,a3;
     private ValueAnimator a4,a5;
@@ -481,6 +482,154 @@
         });
     }
 
+    @SmallTest
+    public void testClone() throws Throwable {
+        // Set up an AnimatorSet and two clones, add one listener to each. When the clones animate,
+        // listeners of both the clone and the animator being cloned should receive animation
+        // lifecycle events.
+        final AnimatorSet s1 = getSequentialSet();
+
+        // Record animators that called their listeners for the corresponding event.
+        final ArrayList<Animator> startedAnimators = new ArrayList<>();
+        final ArrayList<Animator> canceledAnimators = new ArrayList<>();
+        final ArrayList<Animator> endedAnimators = new ArrayList<>();
+
+        final MyListener l1 = new MyListener() {
+            @Override
+            public void onAnimationStart(Animator anim) {
+                super.onAnimationStart(anim);
+                startedAnimators.add(anim);
+            }
+
+            @Override
+            public void onAnimationCancel(Animator anim) {
+                super.onAnimationCancel(anim);
+                canceledAnimators.add(anim);
+            }
+
+            @Override
+            public void onAnimationEnd(Animator anim) {
+                super.onAnimationEnd(anim);
+                endedAnimators.add(anim);
+            }
+
+        };
+        s1.addListener(l1);
+
+        // Start the animation, and make the first clone during its run and the second clone once
+        // it ends.
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(l1.startIsCalled);
+                assertFalse(l1.endIsCalled);
+
+                s1.start();
+            }
+        });
+
+        // Make the first clone, during the animation's run.
+        assertTrue(s1.isStarted());
+        final AnimatorSet s2 = s1.clone();
+        final MyListener l2 = new MyListener();
+        s2.addListener(l2);
+
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                s1.end();
+            }
+        });
+
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(l1.startIsCalled);
+                assertTrue(l1.endIsCalled);
+            }
+        });
+        Thread.sleep(POLL_INTERVAL);
+
+        // Make the second clone now.
+        final AnimatorSet s3 = s1.clone();
+        final MyListener l3 = new MyListener();
+        s3.addListener(l3);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Checking the fields before animations start.
+                assertFalse(l2.startIsCalled);
+                assertFalse(l2.cancelIsCalled);
+                assertFalse(l2.endIsCalled);
+                assertFalse(l3.startIsCalled);
+                assertFalse(l3.cancelIsCalled);
+                assertFalse(l3.endIsCalled);
+
+                s2.start();
+                s3.start();
+            }
+        });
+
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Make sure the listeners receive the callbacks
+                // At this time only onAnimationStart() should be called.
+                assertTrue(l2.startIsCalled);
+                assertTrue(l3.startIsCalled);
+                assertFalse(l2.endIsCalled);
+                assertFalse(l3.endIsCalled);
+                assertFalse(l2.cancelIsCalled);
+                assertFalse(l3.cancelIsCalled);
+
+                s2.end();
+                s3.cancel();
+            }
+        });
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Check that the new listeners for the new animations gets called for the events.
+                assertTrue(l2.startIsCalled);
+                assertFalse(l2.cancelIsCalled);
+                assertTrue(l2.endIsCalled);
+                assertTrue(l3.startIsCalled);
+                assertTrue(l3.cancelIsCalled);
+                assertTrue(l3.endIsCalled);
+
+                // Check that the listener on the animation that was being clone receive the
+                // animation lifecycle events for the clones.
+                assertTrue(onlyContains(startedAnimators, s1, s2, s3));
+                assertTrue(onlyContains(canceledAnimators, s3));
+                assertTrue(onlyContains(endedAnimators, s1, s2, s3));
+            }
+        });
+
+    }
+
+    /**
+     * Check that the animator list contains exactly the given animators and nothing else.
+     */
+    private boolean onlyContains(ArrayList<Animator> animators, AnimatorSet... sets) {
+        if (sets.length != animators.size()) {
+            return false;
+        }
+
+        for (int i = 0; i < sets.length; i++) {
+            AnimatorSet set = sets[i];
+            if (!animators.contains(set)) {
+                return false;
+            }
+        }
+        return true;
+
+    }
+
     // Create an AnimatorSet with all the animators running sequentially
     private AnimatorSet getSequentialSet() {
         AnimatorSet set = new AnimatorSet();
diff --git a/core/tests/coretests/src/android/animation/AutoCancelTest.java b/core/tests/coretests/src/android/animation/AutoCancelTest.java
index b1f88db..5810818 100644
--- a/core/tests/coretests/src/android/animation/AutoCancelTest.java
+++ b/core/tests/coretests/src/android/animation/AutoCancelTest.java
@@ -18,10 +18,12 @@
 import android.os.Handler;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
 
 import java.util.HashMap;
 import java.util.concurrent.TimeUnit;
 
+@Suppress  // Failing
 public class AutoCancelTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
 
     boolean mAnimX1Canceled = false;
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index 2615a28..e6d3158 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -28,7 +28,6 @@
 import android.net.Uri;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -37,7 +36,6 @@
 import java.util.List;
 
 /** Unit test for SettingsProvider. */
-@Suppress  // Failing.
 public class SettingsProviderTest extends AndroidTestCase {
     @MediumTest
     public void testNameValueCache() {
@@ -53,84 +51,108 @@
         assertEquals(1, r.delete(Settings.Secure.getUriFor("test_service"), null, null));
         assertEquals(null, Settings.Secure.getString(r, "test_service"));
 
-        // Try all the same things in the System table
-        Settings.System.putString(r, "test_setting", "Value");
-        assertEquals("Value", Settings.System.getString(r, "test_setting"));
-
-        Settings.System.putString(r, "test_setting", "New");
-        assertEquals("New", Settings.System.getString(r, "test_setting"));
-
-        assertEquals(1, r.delete(Settings.System.getUriFor("test_setting"), null, null));
-        assertEquals(null, Settings.System.getString(r, "test_setting"));
+        // Apps should not be able to use System settings.
+        try {
+            Settings.System.putString(r, "test_setting", "Value");
+            fail("IllegalArgumentException expected");
+        } catch (java.lang.IllegalArgumentException e) {
+            // expected
+        }
     }
 
     @MediumTest
-    public void testRowNameContentUri() {
+    public void testRowNameContentUriForSecure() {
+        final String testKey = "testRowNameContentUriForSecure";
+        final String testValue = "testValue";
+        final String secondTestValue = "testValueNew";
+
+        try {
+            testRowNameContentUri(Settings.Secure.CONTENT_URI, Settings.Secure.NAME,
+                    Settings.Secure.VALUE, testKey, testValue, secondTestValue);
+        } finally {
+            // clean up
+            Settings.Secure.putString(getContext().getContentResolver(), testKey, null);
+        }
+    }
+
+    @MediumTest
+    public void testRowNameContentUriForSystem() {
+        final String testKey = Settings.System.VIBRATE_ON;
+        assertTrue("Settings.System.PUBLIC_SETTINGS cannot be empty.  We need to use one of it"
+                + " for testing.  Only settings key in this collection will be accepted by the"
+                + " framework.", Settings.System.PUBLIC_SETTINGS.contains(testKey));
+        final String testValue = "0";
+        final String secondTestValue = "1";
+        final String oldValue =
+                Settings.System.getString(getContext().getContentResolver(), testKey);
+
+        try {
+            testRowNameContentUri(Settings.System.CONTENT_URI, Settings.System.NAME,
+                    Settings.System.VALUE, testKey, testValue, secondTestValue);
+        } finally {
+            // restore old value
+            if (oldValue != null) {
+                Settings.System.putString(getContext().getContentResolver(), testKey, oldValue);
+            }
+        }
+    }
+
+    private void testRowNameContentUri(Uri table, String nameField, String valueField,
+            String testKey, String testValue, String secondTestValue) {
         ContentResolver r = getContext().getContentResolver();
 
-        assertEquals("content://settings/system/test_setting",
-                Settings.System.getUriFor("test_setting").toString());
-        assertEquals("content://settings/secure/test_service",
-                Settings.Secure.getUriFor("test_service").toString());
+        ContentValues v = new ContentValues();
+        v.put(nameField, testKey);
+        v.put(valueField, testValue);
 
-        // These tables use the row name (not ID) as their content URI.
-        Uri tables[] = { Settings.System.CONTENT_URI, Settings.Secure.CONTENT_URI };
-        for (Uri table : tables) {
-            ContentValues v = new ContentValues();
-            v.put(Settings.System.NAME, "test_key");
-            v.put(Settings.System.VALUE, "Test");
-            Uri uri = r.insert(table, v);
-            assertEquals(table.toString() + "/test_key", uri.toString());
+        r.insert(table, v);
+        Uri uri = Uri.parse(table.toString() + "/" + testKey);
 
-            // Query with a specific URI and no WHERE clause succeeds.
-            Cursor c = r.query(uri, null, null, null, null);
-            try {
-                assertTrue(c.moveToNext());
-                assertEquals("test_key", c.getString(c.getColumnIndex(Settings.System.NAME)));
-                assertEquals("Test", c.getString(c.getColumnIndex(Settings.System.VALUE)));
-                assertFalse(c.moveToNext());
-            } finally {
-                c.close();
-            }
-
-            // Query with a specific URI and a WHERE clause fails.
-            try {
-                r.query(uri, null, "1", null, null);
-                fail("UnsupportedOperationException expected");
-            } catch (UnsupportedOperationException e) {
-                if (!e.toString().contains("WHERE clause")) throw e;
-            }
-
-            // Query with a tablewide URI and a WHERE clause succeeds.
-            c = r.query(table, null, "name='test_key'", null, null);
-            try {
-                assertTrue(c.moveToNext());
-                assertEquals("test_key", c.getString(c.getColumnIndex(Settings.System.NAME)));
-                assertEquals("Test", c.getString(c.getColumnIndex(Settings.System.VALUE)));
-                assertFalse(c.moveToNext());
-            } finally {
-                c.close();
-            }
-
-            v = new ContentValues();
-            v.put(Settings.System.VALUE, "Toast");
-            assertEquals(1, r.update(uri, v, null, null));
-
-            c = r.query(uri, null, null, null, null);
-            try {
-                assertTrue(c.moveToNext());
-                assertEquals("test_key", c.getString(c.getColumnIndex(Settings.System.NAME)));
-                assertEquals("Toast", c.getString(c.getColumnIndex(Settings.System.VALUE)));
-                assertFalse(c.moveToNext());
-            } finally {
-                c.close();
-            }
-
-            assertEquals(1, r.delete(uri, null, null));
+        // Query with a specific URI and no WHERE clause succeeds.
+        Cursor c = r.query(uri, null, null, null, null);
+        try {
+            assertTrue(c.moveToNext());
+            assertEquals(testKey, c.getString(c.getColumnIndex(nameField)));
+            assertEquals(testValue, c.getString(c.getColumnIndex(valueField)));
+            assertFalse(c.moveToNext());
+        } finally {
+            c.close();
         }
 
-        assertEquals(null, Settings.System.getString(r, "test_key"));
-        assertEquals(null, Settings.Secure.getString(r, "test_key"));
+        // Query with a specific URI and a WHERE clause fails.
+        try {
+            r.query(uri, null, "1", null, null);
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Query with a tablewide URI and a WHERE clause succeeds.
+        c = r.query(table, null, "name='" + testKey + "'", null, null);
+        try {
+            assertTrue(c.moveToNext());
+            assertEquals(testKey, c.getString(c.getColumnIndex(nameField)));
+            assertEquals(testValue, c.getString(c.getColumnIndex(valueField)));
+            assertFalse(c.moveToNext());
+        } finally {
+            c.close();
+        }
+
+        v = new ContentValues();
+        // NAME is still needed, although the uri should be specific enough. Why?
+        v.put(nameField, testKey);
+        v.put(valueField, secondTestValue);
+        assertEquals(1, r.update(uri, v, null, null));
+
+        c = r.query(uri, null, null, null, null);
+        try {
+            assertTrue(c.moveToNext());
+            assertEquals(testKey, c.getString(c.getColumnIndex(nameField)));
+            assertEquals(secondTestValue, c.getString(c.getColumnIndex(valueField)));
+            assertFalse(c.moveToNext());
+        } finally {
+            c.close();
+        }
     }
 
     @MediumTest
@@ -139,7 +161,7 @@
         ContentResolver r = getContext().getContentResolver();
 
         // Make sure there's an owner
-        assertTrue(findUser(um, UserHandle.USER_OWNER));
+        assertTrue(findUser(um, UserHandle.USER_SYSTEM));
 
         // create a new user to use for testing
         UserInfo otherUser = um.createUser("TestUser1", UserInfo.FLAG_GUEST);
@@ -148,21 +170,17 @@
             assertNotSame("Current calling user id should not be the new guest user",
                     otherUser.id, UserHandle.getCallingUserId());
 
-            Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "gps");
-            Settings.Secure.putStringForUser(r,
-                    Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network", otherUser.id);
+            final String testKey = "testSettingsChangeForOtherUser";
+            final String testValue1 = "value1";
+            final String testValue2 = "value2";
+            Settings.Secure.putString(r, testKey, testValue1);
+            Settings.Secure.putStringForUser(r, testKey, testValue2, otherUser.id);
 
-            assertEquals("gps",
-                    Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
-            assertEquals("network", Settings.Secure.getStringForUser(
-                    r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, otherUser.id));
+            assertEquals(testValue1, Settings.Secure.getString(r, testKey));
+            assertEquals(testValue2, Settings.Secure.getStringForUser(r, testKey, otherUser.id));
 
             assertNotSame("Current calling user id should not be the new guest user",
                     otherUser.id, UserHandle.getCallingUserId());
-            Settings.Secure.setLocationProviderEnabledForUser(r, "network", false, otherUser.id);
-            assertEquals("", Settings.Secure.getStringForUser(
-                    r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, otherUser.id));
-
         } finally {
             // Tidy up
             um.removeUser(otherUser.id);
@@ -170,6 +188,7 @@
     }
 
     @MediumTest
+    @Suppress  // Settings.Bookmarks uses a query format that's not supported now.
     public void testRowNumberContentUri() {
         ContentResolver r = getContext().getContentResolver();
 
@@ -196,47 +215,56 @@
     public void testParseProviderList() {
         ContentResolver r = getContext().getContentResolver();
 
-        // Make sure we get out what we put in.
-        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
-                "test1,test2,test3");
-        assertEquals(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED),
-                "test1,test2,test3");
-
+        // We only accept "+value" and "-value"
         // Test adding a value
-        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
-                "");
         Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test1");
-        assertEquals("test1",
-                Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test1"));
 
         // Test adding a second value
         Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test2");
-        assertEquals("test1,test2",
-                Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test1"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test2"));
 
         // Test adding a third value
         Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test3");
-        assertEquals("test1,test2,test3",
-                Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test1"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test2"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test3"));
 
         // Test deleting the first value in a 3 item list
         Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test1");
-        assertEquals("test2,test3",
-                Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+        assertFalse(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test1"));
 
         // Test deleting the middle value in a 3 item list
-        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
-                "test1,test2,test3");
-        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test2");
-        assertEquals("test1,test3",
-                Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test4");
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test2"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test3"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test4"));
+        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test3");
+        assertFalse(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test3"));
 
         // Test deleting the last value in a 3 item list
-        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
-                "test1,test2,test3");
-        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test3");
-        assertEquals("test1,test2",
-                Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test5");
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test2"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test4"));
+        assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test5"));
+        Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test5");
+        assertFalse(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+                .contains("test5"));
      }
 
     private boolean findUser(UserManager um, int userHandle) {
@@ -254,7 +282,7 @@
         ContentResolver r = getContext().getContentResolver();
 
         // Make sure there's an owner
-        assertTrue(findUser(um, UserHandle.USER_OWNER));
+        assertTrue(findUser(um, UserHandle.USER_SYSTEM));
 
         // create a new user to use for testing
         UserInfo user = um.createUser("TestUser1", UserInfo.FLAG_GUEST);
@@ -266,12 +294,12 @@
             final int SELF_VALUE = 40;
             final int OTHER_VALUE = 27;
 
-            Settings.System.putInt(r, TEST_KEY, SELF_VALUE);
-            Settings.System.putIntForUser(r, TEST_KEY, OTHER_VALUE, user.id);
+            Settings.Secure.putInt(r, TEST_KEY, SELF_VALUE);
+            Settings.Secure.putIntForUser(r, TEST_KEY, OTHER_VALUE, user.id);
 
             // Verify that they read back as intended
-            int myValue = Settings.System.getInt(r, TEST_KEY, 0);
-            int otherValue = Settings.System.getIntForUser(r, TEST_KEY, 0, user.id);
+            int myValue = Settings.Secure.getInt(r, TEST_KEY, 0);
+            int otherValue = Settings.Secure.getIntForUser(r, TEST_KEY, 0, user.id);
             assertTrue("Running as user " + UserHandle.myUserId()
                     + " and reading/writing as user " + user.id
                     + ", expected to read " + SELF_VALUE + " but got " + myValue,
@@ -310,7 +338,8 @@
         assertCanBeHandled(new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
         assertCanBeHandled(new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS));
         assertCanBeHandled(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
-        assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
+        //TODO: seems no one is using this anymore.
+//        assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
         assertCanBeHandled(new Intent(Settings.ACTION_SEARCH_SETTINGS));
         assertCanBeHandled(new Intent(Settings.ACTION_SECURITY_SETTINGS));
         assertCanBeHandled(new Intent(Settings.ACTION_SETTINGS));
diff --git a/core/tests/coretests/src/android/widget/listview/ListManagedCursorTest.java b/core/tests/coretests/src/android/widget/listview/ListManagedCursorTest.java
index 7938cba..bc3776c 100644
--- a/core/tests/coretests/src/android/widget/listview/ListManagedCursorTest.java
+++ b/core/tests/coretests/src/android/widget/listview/ListManagedCursorTest.java
@@ -17,8 +17,7 @@
 package android.widget.listview;
 
 import android.app.Instrumentation;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.FlakyTest;
+import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.view.KeyEvent;
@@ -28,12 +27,12 @@
 /**
  * Tests restoring the scroll position in a list with a managed cursor.
  */
-public class ListManagedCursorTest extends ActivityInstrumentationTestCase<ListManagedCursor> {
+public class ListManagedCursorTest extends ActivityInstrumentationTestCase2<ListManagedCursor> {
     private ListManagedCursor mActivity;
     private ListView mListView;
 
     public ListManagedCursorTest() {
-        super("com.android.frameworks.coretests", ListManagedCursor.class);
+        super(ListManagedCursor.class);
     }
 
     @Override
@@ -48,86 +47,46 @@
     public void testPreconditions() {
         assertNotNull(mActivity);
         assertNotNull(mListView);
-        
+
         assertEquals(0, mListView.getFirstVisiblePosition());
     }
-    
+
     /**
      * Scroll the list using arrows, launch new activity, hit back, make sure we're still scrolled.
      */
     @LargeTest
     public void testKeyScrolling() {
         Instrumentation inst = getInstrumentation();
-        
+
         int firstVisiblePosition = arrowScroll(inst);
-        
+
         inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
         inst.waitForIdleSync();
-        
-        assertTrue("List changed to touch mode", !mListView.isInTouchMode()); 
-        assertTrue("List did not preserve scroll position", 
-                firstVisiblePosition == mListView.getFirstVisiblePosition()); 
+
+        assertTrue("List changed to touch mode", !mListView.isInTouchMode());
+        assertTrue("List did not preserve scroll position",
+                firstVisiblePosition == mListView.getFirstVisiblePosition());
     }
 
     /**
-     * Scroll the list using touch, launch new activity, hit back, make sure we're still scrolled.
-     */
-    @LargeTest
-    public void testTouchScrolling() {
-        Instrumentation inst = getInstrumentation();
-        
-       int firstVisiblePosition = touchScroll(inst);
-        
-        inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
-        inst.waitForIdleSync();
-        
-        assertTrue("List not in touch mode", mListView.isInTouchMode()); 
-        assertTrue("List did not preserve scroll position", 
-                firstVisiblePosition == mListView.getFirstVisiblePosition()); 
-    }
-    
-    /**
      * Scroll the list using arrows, launch new activity, change to touch mode, hit back, make sure
      * we're still scrolled.
      */
     @LargeTest
     public void testKeyScrollingToTouchMode() {
         Instrumentation inst = getInstrumentation();
-        
+
         int firstVisiblePosition = arrowScroll(inst);
-        
-        TouchUtils.dragQuarterScreenUp(this);
+
+        TouchUtils.dragQuarterScreenUp(this, getActivity());
         inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
         inst.waitForIdleSync();
-        
-        assertTrue("List did not change to touch mode", mListView.isInTouchMode()); 
-        assertTrue("List did not preserve scroll position", 
-                firstVisiblePosition == mListView.getFirstVisiblePosition()); 
+
+        assertTrue("List did not change to touch mode", mListView.isInTouchMode());
+        assertTrue("List did not preserve scroll position",
+                firstVisiblePosition == mListView.getFirstVisiblePosition());
     }
 
-
-    /**
-     * Scroll the list using touch, launch new activity, change to trackball mode, hit back, make
-     * sure we're still scrolled.
-     */
-    @FlakyTest(tolerance=3)
-    @LargeTest
-    public void testTouchScrollingToTrackballMode() {
-        Instrumentation inst = getInstrumentation();
-
-        int firstVisiblePosition = touchScroll(inst);
-
-        inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
-        inst.waitForIdleSync();
-        inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
-        inst.waitForIdleSync();
-        inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
-        inst.waitForIdleSync();
-        assertTrue("List not in trackball mode", !mListView.isInTouchMode());
-        assertTrue("List did not preserve scroll position", firstVisiblePosition == mListView
-                .getFirstVisiblePosition());
-    }
-    
     public int arrowScroll(Instrumentation inst) {
         int count = mListView.getChildCount();
 
@@ -151,30 +110,4 @@
 
         return firstVisiblePosition;
     }
-
-    public int touchScroll(Instrumentation inst) {
-        TouchUtils.dragQuarterScreenUp(this);
-        inst.waitForIdleSync();
-        TouchUtils.dragQuarterScreenUp(this);
-        inst.waitForIdleSync();
-        TouchUtils.dragQuarterScreenUp(this);
-        inst.waitForIdleSync();
-        TouchUtils.dragQuarterScreenUp(this);
-        inst.waitForIdleSync();
-
-        int firstVisiblePosition = mListView.getFirstVisiblePosition();
-        assertTrue("Touch scroll did not happen", firstVisiblePosition > 0);
-        assertTrue("List not in touch mode", mListView.isInTouchMode());
-
-        TouchUtils.clickView(this, mListView.getChildAt(mListView.getChildCount() - 1));
-        inst.waitForIdleSync();
-
-        try {
-            Thread.sleep(3000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-
-        return firstVisiblePosition;
-    }
 }
diff --git a/docs/html/training/auto/start/index.jd b/docs/html/training/auto/start/index.jd
index f6cdbd1..6c6f188 100644
--- a/docs/html/training/auto/start/index.jd
+++ b/docs/html/training/auto/start/index.jd
@@ -177,7 +177,7 @@
      href="https://play.google.com/store/apps/details?id=com.google.android.projection.gearhead&hl=en"
      >Android Auto app</a> on the mobile device.</li>
   <li>Open the <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> and
-    download the DHU package <strong>Android Auto Desktop Head Unit</strong> from the
+    download the DHU package <strong>Android Auto Desktop Head Unit emulator</strong> from the
     <em>SDK Tools</em> tab. The DHU installs in the <code>&lt;sdk&gt;/extras/google/auto/</code>
     directory.</li>
   <li>If you are running the DHU on Linux, you must also install
diff --git a/docs/html/training/sign-in/index.jd b/docs/html/training/sign-in/index.jd
index 9d49fd9..d7c8e1d 100644
--- a/docs/html/training/sign-in/index.jd
+++ b/docs/html/training/sign-in/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding Sign-In
-page.tags=authentication,signin,social,google+
+page.tags=authentication,signin
 page.article=true
 page.trainingcourse=true
 @jd:body
@@ -11,13 +11,13 @@
   alt="Google maps sample image">
 
 <p>
-  The Google+ platform for Android lets you authenticate a user with the same credentials they use
-  on Google every day. Once a user signs in with Google, you can create more engaging experiences
-  and drive usage of your app.
+  Google Sign-In for Android lets you authenticate a user with the same credentials they use on 
+  Google. After a user signs in with Google, you can create more engaging experiences and drive 
+  usage of your app.
 </p>
 
 <p>
-  The <a href="https://developers.google.com/+/mobile/android/">Google+ Android API</a> allows
+  The <a href="https://developers.google.com/identity/sign-in/android/">Google Android API</a> allows
   you to integrate sign-in and social features into your app.
 </p>
 
@@ -26,43 +26,27 @@
 
 <h4>Trusted authentication</h4>
 <p>
-  Google+ Sign-In is a simple, trusted, and secure way to let people sign in to your app with their
-  Google credentials and bring along their Google+ info.<br>
-  <a href="https://developers.google.com/+/mobile/android/sign-in" class="external-link">Add
-  sign-in</a>.
+  Google Sign-In is a simple, trusted, and secure way to let people sign in to your app with their
+  Google credentials.<br>
+  <a href="https://developers.google.com/identity/sign-in/android/sign-in" class="external-link">Add
+  Sign-in</a>.
 </p>
 
 <h4>Access the profile and social graph</h4>
 <p>
-  Once users have signed in with Google, your app can welcome them by name, display their picture,
-  connect them with friends, and lots more.<br>
-  <a href="https://developers.google.com/+/mobile/android/people" class="external-link">Access the
-  social graph</a>.
-</p>
-
-<h4>Stand out in the stream</h4>
-<p>
-  Interactive posts is a rich way of sharing to Google+. It lets users prompt friends to take
-  specific actions in your app from a Google+ post, like "listen," "RSVP," "check-in," and over 100
-  more actions.<br>
-  <a class="external-link" href="https://developers.google.com/+/mobile/android/share">Post
-  interactive content</a>.
-</p>
-
-<h4>Recommend content</h4>
-<p>
-  Add a native +1 button so users can recommend content from your app. These endorsements can give
-  your app more credibility and help it grow faster.<br>
-  <a class="external-link" href="https://developers.google.com/+/mobile/android/recommend">Add the
-  +1 button</a>.
+  After users have signed in with Google, your app can welcome them by name and display their 
+  picture. If your app requests social scopes, it can connect users with friends, and access  
+  age range, language, and public profile information.<br>
+  <a href="https://developers.google.com/identity/sign-in/android/people" class="external-link">
+  Getting Profile Information</a>.
 </p>
 
 
 <h2 id="start">Get Started</h2>
 <p>
-  The Google+ Android APIs are part of the Google Play services platform. To use Google+ features,
+  The Google Android APIs are part of the Google Play services platform. To use Google features,
   set up the Google Play services SDK in your app development project. For more information, see
   the <a class="external-link" href=
-  "https://developers.google.com/+/mobile/android/getting-started">Getting Started</a> guide for
-  the Google+ Platform for Android
+  "https://developers.google.com/identity/sign-in/android/start-integrating">Start Integrating</a> 
+  guide for Google Sign-In.
 </p>
\ No newline at end of file
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 1857345..abb51db 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -217,7 +217,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         return mAnimatedVectorState.mVectorDrawable.setLevel(level);
     }
 
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index e1975c9..521c74b 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -105,10 +105,12 @@
     /**
      * Sets whether this AnimationDrawable is visible.
      * <p>
-     * When the drawable becomes invisible, it will pause its animation. A
-     * subsequent change to visible with <code>restart</code> set to true will
-     * restart the animation from the first frame. If <code>restart</code> is
-     * false, the animation will resume from the most recent frame.
+     * When the drawable becomes invisible, it will pause its animation. A subsequent change to
+     * visible with <code>restart</code> set to true will restart the animation from the
+     * first frame. If <code>restart</code> is false, the drawable will resume from the most recent
+     * frame. If the drawable has already reached the last frame, it will then loop back to the
+     * first frame, unless it's a one shot drawable (set through {@link #setOneShot(boolean)}),
+     * in which case, it will stay on the last frame.
      *
      * @param visible true if visible, false otherwise
      * @param restart when visible, true to force the animation to restart
@@ -120,7 +122,7 @@
         final boolean changed = super.setVisible(visible, restart);
         if (visible) {
             if (restart || changed) {
-                boolean startFromZero = restart || !mRunning ||
+                boolean startFromZero = restart || (!mRunning && !mAnimationState.mOneShot) ||
                         mCurFrame >= mAnimationState.getChildCount();
                 setFrame(startFromZero ? 0 : mCurFrame, true, mAnimating);
             }
@@ -131,7 +133,7 @@
     }
 
     /**
-     * Starts the animation, looping if necessary. This method has no effect
+     * Starts the animation from the first frame, looping if necessary. This method has no effect
      * if the animation is running.
      * <p>
      * <strong>Note:</strong> Do not call this in the
@@ -158,7 +160,7 @@
     }
 
     /**
-     * Stops the animation. This method has no effect if the animation is not
+     * Stops the animation at the current frame. This method has no effect if the animation is not
      * running.
      *
      * @see #isRunning()
@@ -169,6 +171,7 @@
         mAnimating = false;
 
         if (isRunning()) {
+            mCurFrame = 0;
             unscheduleSelf(this);
         }
     }
@@ -196,7 +199,6 @@
 
     @Override
     public void unscheduleSelf(Runnable what) {
-        mCurFrame = 0;
         mRunning = false;
         super.unscheduleSelf(what);
     }
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 31fccd0..3b92507 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -52,8 +52,6 @@
     public static final int HORIZONTAL = 1;
     public static final int VERTICAL = 2;
 
-    private static final int MAX_LEVEL = 10000;
-
     private final Rect mTmpRect = new Rect();
 
     private ClipState mState;
@@ -143,7 +141,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
         invalidateSelf();
         return true;
@@ -153,12 +151,12 @@
     public int getOpacity() {
         final Drawable dr = getDrawable();
         final int opacity = dr.getOpacity();
-        if (opacity == PixelFormat.TRANSPARENT || dr.getLevel() == 0) {
+        if (opacity == PixelFormat.TRANSPARENT || dr.getLevelFloat() == 0) {
             return PixelFormat.TRANSPARENT;
         }
 
-        final int level = getLevel();
-        if (level >= MAX_LEVEL) {
+        final float level = getLevelFloat();
+        if (level >= MAX_LEVEL_FLOAT) {
             return dr.getOpacity();
         }
 
@@ -169,24 +167,24 @@
     @Override
     public void draw(Canvas canvas) {
         final Drawable dr = getDrawable();
-        if (dr.getLevel() == 0) {
+        if (dr.getLevelFloat() == 0) {
             return;
         }
 
         final Rect r = mTmpRect;
         final Rect bounds = getBounds();
-        final int level = getLevel();
+        final float level = getLevelFloat();
 
         int w = bounds.width();
-        final int iw = 0; //mState.mDrawable.getIntrinsicWidth();
+        final int iw = 0;
         if ((mState.mOrientation & HORIZONTAL) != 0) {
-            w -= (w - iw) * (MAX_LEVEL - level) / MAX_LEVEL;
+            w -= Math.round((w - iw) * (MAX_LEVEL_FLOAT - level) / MAX_LEVEL_FLOAT);
         }
 
         int h = bounds.height();
-        final int ih = 0; //mState.mDrawable.getIntrinsicHeight();
+        final int ih = 0;
         if ((mState.mOrientation & VERTICAL) != 0) {
-            h -= (h - ih) * (MAX_LEVEL - level) / MAX_LEVEL;
+            h -= Math.round((h - ih) * (MAX_LEVEL_FLOAT - level) / MAX_LEVEL_FLOAT);
         }
 
         final int layoutDirection = getLayoutDirection();
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index b95c183..fb77155 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -41,6 +41,7 @@
 import android.os.Trace;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.FloatProperty;
 import android.util.StateSet;
 import android.util.TypedValue;
 import android.util.Xml;
@@ -126,12 +127,19 @@
  * document.</p></div>
  */
 public abstract class Drawable {
+
     private static final Rect ZERO_BOUNDS_RECT = new Rect();
 
     static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
 
+    /** The standard maximum value for calls to {@link #setLevel(int)}. */
+    public static final int MAX_LEVEL = 10000;
+
+    /** The standard maximum value for calls to {@link #setLevel(float)}. */
+    public static final float MAX_LEVEL_FLOAT = 10000.0f;
+
     private int[] mStateSet = StateSet.WILD_CARD;
-    private int mLevel = 0;
+    private float mLevel = 0.0f;
     private int mChangingConfigurations = 0;
     private Rect mBounds = ZERO_BOUNDS_RECT;  // lazily becomes a new Rect()
     private WeakReference<Callback> mCallback = null;
@@ -711,22 +719,63 @@
     }
 
     /**
-     * Specify the level for the drawable.  This allows a drawable to vary its
-     * imagery based on a continuous controller, for example to show progress
-     * or volume level.
+     * Sets the level for the drawable as an integer value where typically the
+     * minimum level is 0 and the maximum is 10000 {@link #MAX_LEVEL}; however,
+     * the range may vary based on the Drawable implementation and is not
+     * clamped.
+     * <p>
+     * This allows a drawable to vary its imagery based on a continuous
+     * controller. For example, it may be used to show progress or volume
+     * level.
+     * <p>
+     * Use #setLevelFloat(float) to set the level as a high-precision
+     * floating-point value.
      *
-     * <p>If the new level you are supplying causes the appearance of the
-     * Drawable to change, then it is responsible for calling
-     * {@link #invalidateSelf} in order to have itself redrawn, <em>and</em>
-     * true will be returned from this function.
-     *
-     * @param level The new level, from 0 (minimum) to 10000 (maximum).
-     *
-     * @return Returns true if this change in level has caused the appearance
-     * of the Drawable to change (hence requiring an invalidate), otherwise
-     * returns false.
+     * @param level the new level, typically between 0 and 10000
+     * @return {@code true} if this change in level has caused the appearance
+     *         of the drawable to change and will require a subsequent call to
+     *         invalidate, {@code false} otherwise
+     * @see #getLevel()
+     * @see #setLevel(float)
+     * @see #onLevelChange(int)
      */
     public final boolean setLevel(int level) {
+        return setLevel((float) level);
+    }
+
+    /**
+     * Returns the current level as a rounded integer value.
+     * <p>
+     * Use #getLevelFloat() to return the level as a high-precision
+     * floating-point value.
+     *
+     * @return the current level, typically between 0 and 10000
+     * @see #setLevel(int)
+     * @see #getLevelFloat()
+     */
+    public final int getLevel() {
+        return Math.round(mLevel);
+    }
+
+    /**
+     * Sets the level for the drawable as a floating-point value where
+     * typically the minimum level is 0.0 and the maximum is 10000.0
+     * {@link #MAX_LEVEL_FLOAT}; however, the range may vary based on the
+     * Drawable implementation and is not clamped.
+     * <p>
+     * This allows a drawable to vary its imagery based on a continuous
+     * controller. For example, it may be used to show progress or volume
+     * level.
+     *
+     * @param level the new level, typically between 0.0 and 10000.0
+     *              ({@link #MAX_LEVEL_FLOAT})
+     * @return {@code true} if this change in level has caused the appearance
+     *         of the drawable to change and will require a subsequent call to
+     *         invalidate, {@code false} otherwise
+     * @see #getLevelFloat()
+     * @see #onLevelChange(float)
+     */
+    public final boolean setLevel(float level) {
         if (mLevel != level) {
             mLevel = level;
             return onLevelChange(level);
@@ -735,11 +784,13 @@
     }
 
     /**
-     * Retrieve the current level.
+     * Returns the current level as a floating-point value.
      *
-     * @return int Current level, from 0 (minimum) to 10000 (maximum).
+     * @return the current level, typically between 0.0 and 10000.0
+     *         ({@link #MAX_LEVEL_FLOAT})
+     * @see #setLevel(float)
      */
-    public final int getLevel() {
+    public final float getLevelFloat() {
         return mLevel;
     }
 
@@ -894,14 +945,47 @@
      * last state.
      */
     protected boolean onStateChange(int[] state) { return false; }
-    /** Override this in your subclass to change appearance if you vary based
-     *  on level.
-     * @return Returns true if the level change has caused the appearance of
-     * the Drawable to change (that is, it needs to be drawn), else false
-     * if it looks the same and there is no need to redraw it since its
-     * last level.
+
+    /**
+     * Called when the drawable level changes.
+     * <p>
+     * Override this in your subclass to change appearance if you vary based on
+     * level and do not need floating-point accuracy. To handle changes with
+     * higher accuracy, override {@link #onLevelChange(float)} instead.
+     * <p>
+     * <strong>Note:</strong> Do not override both this method and
+     * {@link #onLevelChange(float)}. Only override one method.
+     *
+     * @param level the level as an integer value, typically between 0
+     *              (minimum) and 10000 ({@link #MAX_LEVEL})
+     * @return {@code true} if the level change has caused the appearance of
+     *         the drawable to change such that it needs to be redrawn, or
+     *         {@code false} if there is no need to redraw
      */
     protected boolean onLevelChange(int level) { return false; }
+
+    /**
+     * Called when the drawable level changes.
+     * <p>
+     * Override this in your subclass to change appearance if you vary based on
+     * level and need floating-point accuracy.
+     * <p>
+     * <strong>Note:</strong> Do not override both this method and
+     * {@link #onLevelChange(int)}. Only override one method. If your app
+     * targets SDK <= 23 ({@link android.os.Build.VERSION_CODES#M M}), you
+     * will need to override {@link #onLevelChange(int)} to receive callbacks
+     * on devices running Android M and below.
+     *
+     * @param level the level as a floating-point value, typically between 0.0
+     *              and 10000.0 ({@link #MAX_LEVEL_FLOAT})
+     * @return {@code true} if the level change has caused the appearance of
+     *         the drawable to change such that it needs to be redrawn, or
+     *         {@code false} if there is no need to redraw
+     */
+    protected boolean onLevelChange(float level) {
+        return onLevelChange(Math.round(level));
+    }
+
     /**
      * Override this in your subclass to change appearance if you vary based on
      * the bounds.
@@ -1328,6 +1412,23 @@
     }
 
     /**
+     * Animatable property for Drawable level.
+     *
+     * @hide Until Drawable animations have been cleaned up.
+     */
+    public static final FloatProperty<Drawable> LEVEL = new FloatProperty<Drawable>("levelFloat") {
+        @Override
+        public Float get(Drawable object) {
+            return object.getLevelFloat();
+        }
+
+        @Override
+        public void setValue(Drawable object, float value) {
+            object.setLevel(value);
+        }
+    };
+
+    /**
      * Obtains styled attributes from the theme, if available, or unstyled
      * resources if the theme is null.
      */
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 1915dd7..0210ddb 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -322,7 +322,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         if (mLastDrawable != null) {
             return mLastDrawable.setLevel(level);
         }
@@ -510,7 +510,7 @@
         d.setVisible(isVisible(), true);
         d.setDither(mDrawableContainerState.mDither);
         d.setState(getState());
-        d.setLevel(getLevel());
+        d.setLevel(getLevelFloat());
         d.setBounds(getBounds());
         d.setLayoutDirection(getLayoutDirection());
         d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 9185e1a..57b4db2 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -92,7 +92,7 @@
             // Only call setters for data that's stored in the base Drawable.
             dr.setVisible(isVisible(), true);
             dr.setState(getState());
-            dr.setLevel(getLevel());
+            dr.setLevel(getLevelFloat());
             dr.setBounds(getBounds());
             dr.setLayoutDirection(getLayoutDirection());
 
@@ -286,7 +286,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         return mDrawable != null && mDrawable.setLevel(level);
     }
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index d7fd8a5..15295a0 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -530,8 +530,8 @@
      *                 {@code false} otherwise
      *
      * @see #mutate()
-     * @see #setLevel(int)
-     * @see #getLevel()
+     * @see #setLevel(float)
+     * @see #getLevelFloat()
      * @see #isUseLevel()
      */
     public void setUseLevel(boolean useLevel) {
@@ -764,7 +764,7 @@
         if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath;
         mPathIsDirty = false;
 
-        float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f;
+        float sweep = st.mUseLevelForShape ? (360.0f * getLevelFloat() / MAX_LEVEL_FLOAT) : 360f;
 
         RectF bounds = new RectF(mRect);
 
@@ -990,7 +990,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
         mGradientIsDirty = true;
         mPathIsDirty = true;
@@ -1026,7 +1026,7 @@
                 final float x0, x1, y0, y1;
 
                 if (st.mGradient == LINEAR_GRADIENT) {
-                    final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;
+                    final float level = st.mUseLevel ? getLevelFloat() / MAX_LEVEL_FLOAT : 1.0f;
                     switch (st.mOrientation) {
                     case TOP_BOTTOM:
                         x0 = r.left;            y0 = r.top;
@@ -1080,7 +1080,7 @@
                     }
 
                     if (st.mUseLevel) {
-                        radius *= getLevel() / 10000.0f;
+                        radius *= getLevelFloat() / MAX_LEVEL_FLOAT;
                     }
 
                     mGradientRadius = radius;
@@ -1115,7 +1115,7 @@
                             tempPositions = st.mTempPositions = new float[length + 1];
                         }
 
-                        final float level = getLevel() / 10000.0f;
+                        final float level = getLevelFloat() / MAX_LEVEL_FLOAT;
                         for (int i = 0; i < length; i++) {
                             tempPositions[i] = i * fraction * level;
                         }
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 1a0ba6f..c9e38b9 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1400,7 +1400,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         boolean changed = false;
 
         final ChildDrawable[] array = mLayerState.mChildren;
@@ -1733,7 +1733,7 @@
                 clone.setCallback(owner);
                 clone.setLayoutDirection(dr.getLayoutDirection());
                 clone.setBounds(dr.getBounds());
-                clone.setLevel(dr.getLevel());
+                clone.setLevel(dr.getLevelFloat());
             } else {
                 clone = null;
             }
diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java
index b01c643..09d8b6f 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -69,15 +69,16 @@
         if (drawable != null) {
             mLevelListState.addLevel(low, high, drawable);
             // in case the new state matches our current state...
-            onLevelChange(getLevel());
+            onLevelChange(getLevelFloat());
         }
     }
 
     // overrides from Drawable
 
     @Override
-    protected boolean onLevelChange(int level) {
-        int idx = mLevelListState.indexOfLevel(level);
+    protected boolean onLevelChange(float level) {
+        final int nearestLevel = Math.round(level);
+        final int idx = mLevelListState.indexOfLevel(nearestLevel);
         if (selectDrawable(idx)) {
             return true;
         }
@@ -141,7 +142,7 @@
             mLevelListState.addLevel(low, high, dr);
         }
 
-        onLevelChange(getLevel());
+        onLevelChange(getLevelFloat());
     }
 
     @Override
@@ -240,7 +241,7 @@
     private LevelListDrawable(LevelListState state, Resources res) {
         final LevelListState as = new LevelListState(state, this, res);
         setConstantState(as);
-        onLevelChange(getLevel());
+        onLevelChange(getLevelFloat());
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 036a078..71c9977 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -303,10 +303,10 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
 
-        final float value = level / (float) MAX_LEVEL;
+        final float value = level / (float) MAX_LEVEL_FLOAT;
         final float degrees = MathUtils.lerp(mState.mFromDegrees, mState.mToDegrees, value);
         mState.mCurrentDegrees = degrees;
 
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 0acbeda..38c6b80 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -50,8 +50,6 @@
  * @attr ref android.R.styleable#ScaleDrawable_drawable
  */
 public class ScaleDrawable extends DrawableWrapper {
-    private static final int MAX_LEVEL = 10000;
-
     private final Rect mTmpRect = new Rect();
 
     private ScaleState mState;
@@ -170,7 +168,7 @@
     @Override
     public void draw(Canvas canvas) {
         final Drawable d = getDrawable();
-        if (d != null && d.getLevel() != 0) {
+        if (d != null && d.getLevelFloat() != 0) {
             d.draw(canvas);
         }
     }
@@ -178,12 +176,12 @@
     @Override
     public int getOpacity() {
         final Drawable d = getDrawable();
-        if (d.getLevel() == 0) {
+        if (d.getLevelFloat() == 0) {
             return PixelFormat.TRANSPARENT;
         }
 
         final int opacity = d.getOpacity();
-        if (opacity == PixelFormat.OPAQUE && d.getLevel() < MAX_LEVEL) {
+        if (opacity == PixelFormat.OPAQUE && d.getLevelFloat() < MAX_LEVEL_FLOAT) {
             return PixelFormat.TRANSLUCENT;
         }
 
@@ -191,7 +189,7 @@
     }
 
     @Override
-    protected boolean onLevelChange(int level) {
+    protected boolean onLevelChange(float level) {
         super.onLevelChange(level);
         onBoundsChange(getBounds());
         invalidateSelf();
@@ -203,18 +201,20 @@
         final Drawable d = getDrawable();
         final Rect r = mTmpRect;
         final boolean min = mState.mUseIntrinsicSizeAsMin;
-        final int level = getLevel();
+        final float level = getLevelFloat();
 
         int w = bounds.width();
         if (mState.mScaleWidth > 0) {
             final int iw = min ? d.getIntrinsicWidth() : 0;
-            w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);
+            w -= (int) ((w - iw) * (MAX_LEVEL_FLOAT - level)
+                    * mState.mScaleWidth / MAX_LEVEL_FLOAT);
         }
 
         int h = bounds.height();
         if (mState.mScaleHeight > 0) {
             final int ih = min ? d.getIntrinsicHeight() : 0;
-            h -= (int) ((h - ih) * (MAX_LEVEL - level) * mState.mScaleHeight / MAX_LEVEL);
+            h -= (int) ((h - ih) * (MAX_LEVEL_FLOAT - level)
+                    * mState.mScaleHeight / MAX_LEVEL_FLOAT);
         }
 
         final int layoutDirection = getLayoutDirection();
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 6aa41e0..0053f22 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Skuif tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers.</item>
       <item quantity="one">Skuif tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Vee tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers uit.</item>
+      <item quantity="one">Vee tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer uit.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Ontdoen"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Maak tans gereed vir kopieer …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Berei tans voor vir skuif …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index 9a2051e..eb88830 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመውሰድ ላይ።</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመውሰድ ላይ።</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመሰረዝ ላይ።</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመሰረዝ ላይ።</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"ቀልብስ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ቅጂ በማዘጋጀት ላይ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ለመውሰድ በማዘጋጀት ላይ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 18d8f41..bf464b6 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -81,6 +81,15 @@
       <item quantity="other">جارٍ نقل <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات.</item>
       <item quantity="one">جارٍ نقل <xliff:g id="COUNT_0">%1$d</xliff:g> ملف واحد.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="zero">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف.</item>
+      <item quantity="two">جارٍ حذف ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>).</item>
+      <item quantity="few">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
+      <item quantity="many">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا.</item>
+      <item quantity="other">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات.</item>
+      <item quantity="one">جارٍ حذف <xliff:g id="COUNT_0">%1$d</xliff:g> ملف.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"تراجع"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"جارٍ التحضير للنسخ ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"جارٍ التحضير للنقل…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 8c6c502..0bd01a5 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl köçürülür.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl köçürülür.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl silinir.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl silinir.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Ləğv edin"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmaq üçün hazırlanır ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Köçürmə üçün hazırlanır..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index bd14ea5..669145e 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла се преместват.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл се премества.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Изтриват се <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+      <item quantity="one">Изтрива се <xliff:g id="COUNT_0">%1$d</xliff:g> файл.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Отмяна"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Подготвя се за копиране…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Преместването се подготвя…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index ded6042..240ba6c 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো হচ্ছে৷</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো হচ্ছে৷</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা হচ্ছে।</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা হচ্ছে।</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"অনুলিপি করার জন্য প্রস্তুত করা হচ্ছে..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"সরানোর জন্য প্রস্তুত হচ্ছে..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 336e71b..30accda 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">S\'estan movent <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
       <item quantity="one">S\'està movent <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">S\'estan suprimint <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
+      <item quantity="one">S\'està suprimint <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Desfés"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"S\'està preparant una còpia…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"S\'està preparant per moure\'ls..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index 6f969ba..cb1d973 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="other">Přesouvá se <xliff:g id="COUNT_1">%1$d</xliff:g> souborů.</item>
       <item quantity="one">Přesouvá se <xliff:g id="COUNT_0">%1$d</xliff:g> soubor.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="few">Mazání <xliff:g id="COUNT_1">%1$d</xliff:g> souborů.</item>
+      <item quantity="many">Mazání <xliff:g id="COUNT_1">%1$d</xliff:g> souboru.</item>
+      <item quantity="other">Mazání <xliff:g id="COUNT_1">%1$d</xliff:g> souborů.</item>
+      <item quantity="one">Mazání <xliff:g id="COUNT_0">%1$d</xliff:g> souboru.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Vrátit zpět"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Příprava na kopírování…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Příprava na přesunutí…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index a2b570e..f12737c 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Flytter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
       <item quantity="other">Flytter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer slettes.</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer slettes.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Fortryd"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Forbereder flytning…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 1f194c5..a7be4db 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden verschoben.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird verschoben.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden gelöscht.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird gelöscht.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Rückgängig machen"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopieren wird vorbereitet…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Verschieben wird vorbereitet…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index c95a8a5..82155a8 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Μετακίνηση <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
       <item quantity="one">Μετακίνηση <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Διαγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
+      <item quantity="one">Διαγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Αναίρεση"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Προετοιμασία για μετακίνηση…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index b56642f..c609047 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
       <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index b56642f..c609047 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
       <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index b56642f..c609047 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
       <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+      <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 4655d67..5936d83 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Moviendo <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
       <item quantity="one">Moviendo <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Se están borrando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+      <item quantity="one">Se está borrando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Deshacer"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparación para mover archivos…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 1f985ea..2ed67dd 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Moviendo <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
       <item quantity="one">Moviendo <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Eliminando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+      <item quantity="one">Eliminando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Deshacer"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index de92348..e32936f 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Teisaldatakse <xliff:g id="COUNT_1">%1$d</xliff:g> faili.</item>
       <item quantity="one">Teisaldatakse <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Kustutatakse <xliff:g id="COUNT_1">%1$d</xliff:g> faili.</item>
+      <item quantity="one">Kustutatakse <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Võta tagasi"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopeerimise ettevalmistamine …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Teisaldamise ettevalmistamine …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index 5808045..a1b6fc2 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi mugitzen.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi mugitzen.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi ezabatzen ari dira.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi ezabatzen ari da.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Desegin"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopiatzeko prestatzen…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Mugitzeko prestatzen…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index a857ee7..bbbfe52 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">در حال انتقال <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
       <item quantity="other">در حال انتقال <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">در حال حذف <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
+      <item quantity="other">در حال حذف <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"لغو"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"در حال آماده‌سازی برای کپی..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"درحال آماده‌سازی برای انتقال…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index df21358a..fd289a7 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Siirretään <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
       <item quantity="one">Siirretään <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Poistetaan <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
+      <item quantity="one">Poistetaan <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Kumoa"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Valmistellaan kopiointia…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Valmistellaan siirtämistä…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index f86175a..342fc97 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours.</item>
       <item quantity="other">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier.</item>
+      <item quantity="other">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Annuler"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Préparation du déplacement..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index de4a6fc..7434e2f 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
       <item quantity="other">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
+      <item quantity="other">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Annuler"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Préparation au déplacement…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index c5f46f9..b74018d 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
       <item quantity="one">Movendo <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Eliminando <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+      <item quantity="one">Eliminando <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Desfacer"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparándose para mover..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index 9c48562..58384c9 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી રહ્યાં છે.</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી રહ્યાં છે.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખી રહ્યાં છે.</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખી રહ્યાં છે.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"પૂર્વવત્ કરો"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"કૉપિ માટે તૈયારી કરી રહ્યું છે…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ખસેડવા માટે તૈયાર કરી રહ્યું છે…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index 38d2f8e..b42c69c 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें ले जाई जा रही हैं.</item>
       <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें ले जाई जा रही हैं.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाई जा रही हैं.</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाई जा रही हैं.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"कॉपी करने की तैयारी हो रही है…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ले जाने की तैयारी हो रही है…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 90c050b..575c7ff 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -75,6 +75,12 @@
       <item quantity="few">Premještanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
       <item quantity="other">Premještanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+      <item quantity="few">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+      <item quantity="other">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Poništi"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Priprema za kopiranje…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Priprema za premještanje…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 0b9d562..2d2e3c8 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl áthelyezése.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl áthelyezése.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl törlése.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl törlése.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Visszavonás"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Felkészülés a másolásra…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Áthelyezés előkészítése…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 6b0816d..0a4e7a3 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի տեղափոխում:</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի տեղափոխում:</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի ջնջում:</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի ջնջում:</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Հետարկել"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Պատճենման նախապատրաստում…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Տեղափոխման նախապատրաստում…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index 581d8ab..59aadf1 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Memindahkan <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
       <item quantity="one">Memindahkan <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Menghapus <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+      <item quantity="one">Menghapus <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Urungkan"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Menyiapkan salinan..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Menyiapkan pemindahan…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index 668d2f9..a0f4987 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Færir <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
       <item quantity="other">Færir <xliff:g id="COUNT_1">%1$d</xliff:g> skrár.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Eyðir <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
+      <item quantity="other">Eyðir <xliff:g id="COUNT_1">%1$d</xliff:g> skrám.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Afturkalla"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Undirbúningur fyrir afritun…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Flutningur undirbúinn…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index fe16e63..ce837da 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Spostamento di <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
       <item quantity="one">Spostamento di <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Eliminazione di <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+      <item quantity="one">Eliminazione di <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Annulla"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparazione alla copia…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparazione dello spostamento…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 032c545..89e6403 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="other">מעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
       <item quantity="one">מעביר קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="two">מוחק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+      <item quantity="many">מוחק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+      <item quantity="other">מוחק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+      <item quantity="one"> מוחק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"בטל"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"מתכונן להעברה…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 0c9cb6f..92e1023 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>個のファイルを移動しています。</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>個のファイルを移動しています。</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件のファイルを削除しています。</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>件のファイルを削除しています。</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"元に戻す"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"コピーの準備をしています…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"移動の準備をしています…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index 676476f..9a324ba 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">გადაადგილდება <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი.</item>
       <item quantity="one">გადაადგილდება <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">მიმდინარეობს <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის წაშლა.</item>
+      <item quantity="one">მიმდინარეობს <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის წაშლა.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"დაბრუნება"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"მომზადება კოპირებისთვის…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"გადაადგილება მზადდება..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 7655a2d..66f69f5 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл орын ауыстыруда.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл орын ауыстыруда.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жойылуда.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жойылуда.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Кері қайтару"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Көшіруге дайындау…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Тасымалдауға дайындалуда..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index bec2980..5249d97 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">កំពុងផ្លាស់ទីឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g>។</item>
       <item quantity="one">កំពុងផ្លាស់ទីឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g>។</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">កំពុងលុបឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">កំពុងលុបឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"មិនធ្វើវិញ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"កំពុងរៀបចំចម្លង…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"កំពុងរៀបចំផ្លាស់ទី…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index 121197e..d5eda84 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗುತ್ತಿದೆ.</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗುತ್ತಿದೆ.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ.</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ಸರಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index 0afb855..77a0df6 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개 이동</item>
       <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개 이동</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개 삭제</item>
+      <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개 삭제</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"실행취소"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"사본 준비 중…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"이동 준비 중…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 1b8b60e..14a6331 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файл жылдырылууда.</item>
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл жылдырылууда.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жок кылынууда.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жок кылынууда.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Артка кайтаруу"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Көчүрүүгө даярдалууда…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Жылдырууга даярдалууда…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 21aae6b..2d099f4 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">ກຳ​ລັງ​ຍ້າຍ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟ​ລ໌.</item>
       <item quantity="one">ກຳ​ລັງ​ຍ້າຍ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">ກຳ​ລັງ​ລຶບ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟ​ລ໌.</item>
+      <item quantity="one">ກຳ​ລັງ​ລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"ບໍ່​ເຮັດ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ກຳ​ລັງ​ກຽມ​ອັດ​ສຳ​ເນົາ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ກຳ​ລັງ​ກະ​ກຽມ​ຍ້າຍ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index df1b98a..7b458add 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="many">Perkeliama <xliff:g id="COUNT_1">%1$d</xliff:g> failo.</item>
       <item quantity="other">Perkeliama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Trinamas <xliff:g id="COUNT_1">%1$d</xliff:g> failas.</item>
+      <item quantity="few">Trinami <xliff:g id="COUNT_1">%1$d</xliff:g> failai.</item>
+      <item quantity="many">Trinama <xliff:g id="COUNT_1">%1$d</xliff:g> failo.</item>
+      <item quantity="other">Trinama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Anuliuoti"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Ruošiamasi kopijuoti…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Ruošiamasi perkelti…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index baf306e..44909ce 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -75,6 +75,12 @@
       <item quantity="one">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> faila pārvietošana.</item>
       <item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu pārvietošana.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="zero">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu dzēšana.</item>
+      <item quantity="one">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> faila dzēšana.</item>
+      <item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu dzēšana.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Atsaukt"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Gatavošanās kopēšanai…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Sagatavošana pārvietošanai…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index 93d9bea..7408d0b 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Се преместува <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
       <item quantity="other">Се преместуваат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Се брише <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+      <item quantity="other">Се бришат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Врати"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Се подготвува за копирање…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Се подготвува за преместување…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index 162991a..af21db9 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ നീക്കുന്നു.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ നീക്കുന്നു.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ഇല്ലാതാക്കുന്നു.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ഇല്ലാതാക്കുന്നു.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"പഴയപടിയാക്കുക"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"പകർപ്പിനായി തയ്യാറെടുക്കുന്നു…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"നീക്കാനൊരുങ്ങുന്നു…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index 9276964..1475e08 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файл зөөж байна.</item>
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл зөөж байна.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлыг устгаж байна.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлыг устгаж байна.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Буцаах"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Хуулбарлахад бэлтгэж байна..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Зөөвөрлөхөд бэлтгэж байна..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 441035d..b7654881 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हलवित आहे.</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हलवित आहे.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हटवित आहे.</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हटवित आहे.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"पूर्ववत करा"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"कॉपी करण्‍यासाठी तयार करीत आहे…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"हलविण्‍यास तयार होत आहे…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index 89a738c..4682957 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Mengalihkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
       <item quantity="one">Mengalihkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Memadam <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
+      <item quantity="one">Memadam <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Buat asal"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Bersedia untuk salin..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Bersedia untuk mengalih…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index a7d740a..a422898 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင် ရွှေ့နေစဉ်</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင် ရွှေ့နေစဉ်</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">ဖိုင် <xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုဖျက်နေသည်။</item>
+      <item quantity="one">ဖိုင် <xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုဖျက်နေသည်။</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"ပြန်ဖျက်ရန်"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"မိတ္တူကူးရန်ပြင်ဆင်နေ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ရွှေ့ရန် ပြင်ဆင်နေသည်…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 09b75c0..5bcc50f 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Flytter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
       <item quantity="one">Flytter <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Sletter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+      <item quantity="one">Sletter <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Angre"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Forbereder flytting …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index 8a73bad..b121035 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू सार्दै।</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फाइलहरु सार्दै।</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू मेट्दै।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फाइल मेट्दै।</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"अनडू गर्नुहोस्"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"सार्नको लागि तयारी गर्दै ..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index 75c35cb..88ef0bf 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden verplaatsen.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand verplaatsen.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden verwijderen.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand verwijderen.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Ongedaan maken"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopiëren voorbereiden…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Verplaatsen voorbereiden…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index 18d9bc3..a55fc27 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਕਰਨਾ।</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਕਰਨਾ।</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਮਿਟਾ ਰਿਹਾ ਹੈ।</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਮਿਟਾ ਰਿਹਾ ਹੈ।</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"ਪਹਿਲਾਂ ਵਰਗਾ ਕਰੋ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ਕਾਪੀ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ਮੂਵ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 0d38933..0099e5a 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="other">Przenoszę <xliff:g id="COUNT_1">%1$d</xliff:g> pliku.</item>
       <item quantity="one">Przenoszę <xliff:g id="COUNT_0">%1$d</xliff:g> plik.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="few">Usuwam <xliff:g id="COUNT_1">%1$d</xliff:g> pliki.</item>
+      <item quantity="many">Usuwam <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
+      <item quantity="other">Usuwam <xliff:g id="COUNT_1">%1$d</xliff:g> pliku.</item>
+      <item quantity="one">Usuwam <xliff:g id="COUNT_0">%1$d</xliff:g> plik.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Cofnij"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Przygotowuję do kopiowania…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Przygotowuję przenoszenie…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index a23ecd0..18506dc 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
       <item quantity="other">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+      <item quantity="other">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Desfazer"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 3b8ec6a..adf6ec9 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">A mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
       <item quantity="one">A mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">A eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+      <item quantity="one">A eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Anular"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"A preparar para copiar…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"A preparar para mover…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index a23ecd0..18506dc 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
       <item quantity="other">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+      <item quantity="other">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Desfazer"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 692fd5a..1b046a3 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -75,6 +75,12 @@
       <item quantity="other">Se mută <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere.</item>
       <item quantity="one">Se mută <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="few">Se șterg <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere.</item>
+      <item quantity="other">Se șterg <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere.</item>
+      <item quantity="one">Se șterge <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Anulați"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Se pregătește copierea..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Se pregătește mutarea…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 2e5840d..84ae160 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="many">Перемещение <xliff:g id="COUNT_1">%1$d</xliff:g> файлов...</item>
       <item quantity="other">Перемещение <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файла…</item>
+      <item quantity="few">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файлов…</item>
+      <item quantity="many">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файлов…</item>
+      <item quantity="other">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файла…</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Отменить"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Подготовка к копированию…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Подготовка…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 2bd7585..d9d5818 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යමින්.</item>
       <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යමින්.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකමින්.</item>
+      <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකමින්.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"අස් කරන්න"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"පිටපතක් සඳහා සූදානම් කරමින්..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ගෙන යාම සඳහා පිළියෙළ කරමින් ..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index e14362d..e0ff5fc 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="other">Presúva sa <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
       <item quantity="one">Presúva sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="few">Odstraňujú sa <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
+      <item quantity="many">Odstraňuje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súboru.</item>
+      <item quantity="other">Odstraňuje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
+      <item quantity="one">Odstraňuje sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Späť"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Pripravuje sa na kopírovanie..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Prebieha príprava na presunutie…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index a0b3737..83e5124 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="few">Premikanje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
       <item quantity="other">Premikanje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
+      <item quantity="two">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datotek</item>
+      <item quantity="few">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datotek</item>
+      <item quantity="other">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datotek</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Razveljavi"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Pripravljanje na kopiranje …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Priprava na premikanje …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index 796c2ea..981daf2 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Po zhvendos <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë.</item>
       <item quantity="one">Po zhvendos <xliff:g id="COUNT_0">%1$d</xliff:g> skedar.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Po fshin <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë.</item>
+      <item quantity="one">Po fshin <xliff:g id="COUNT_0">%1$d</xliff:g> skedar.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Zhbëj"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Po përgatitet për kopjimin…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Po përgatitet për zhvendosjen…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index ee8d495..bd0e9af 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -75,6 +75,12 @@
       <item quantity="few">Премештају се <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
       <item quantity="other">Премешта се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Брише се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+      <item quantity="few">Бришу се <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
+      <item quantity="other">Брише се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Опозови"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Припрема се копирање…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Припрема се премештање..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index d0a4bbc..2569e00 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Flyttar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
       <item quantity="one">Flyttar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Raderar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+      <item quantity="one">Raderar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Ångra"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopieringen förbereds …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Förbereder för att flytta …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index ae9503f..ce186d7 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Inahamisha faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
       <item quantity="one">Inahamisha faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Inafuta faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+      <item quantity="one">Inafuta faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Tendua"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Inaanda kunakili..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Inatayarisha kuhamisha..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index 30289d0..b7b9c09 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகர்த்துகிறது.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகர்த்துகிறது.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நீக்குகிறது.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்குகிறது.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"செயல்தவிர்"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"நகல் தயாராகிறது…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"நகர்த்துவதற்குத் தயார்படுத்துகிறது…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index 46a4114..7a81486 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను తరలిస్తోంది.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను తరలిస్తోంది.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను తొలగిస్తోంది.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను తొలగిస్తోంది.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"చర్య రద్దు చేయి"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"కాపీ చేయడానికి సిద్ధం చేస్తోంది…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"తరలించడానికి సిద్ధమవుతోంది…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index f6e96f7..87c0a73 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">กำลังย้าย <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
       <item quantity="one">กำลังย้าย <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">กำลังลบ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+      <item quantity="one">กำลังลบ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"เลิกทำ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"กำลังเตรียมการคัดลอก…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"กำลังเตรียมการย้าย…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index 6da7eb9..eaef936 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Inililipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
       <item quantity="other">Inililipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Dine-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+      <item quantity="other">Dine-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"I-undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Naghahanda para sa pagkopya…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Naghahanda para sa paglilipat…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 15f70b6..8c0596f 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya taşınıyor.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya taşınıyor.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya siliniyor.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya siliniyor.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Geri al"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmak için hazırlanıyor…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Taşıma için hazırlanıyor…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index 5bf37f4..9bbc59a 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -77,6 +77,13 @@
       <item quantity="many">Переміщення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
       <item quantity="other">Переміщення <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
+      <item quantity="few">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+      <item quantity="many">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+      <item quantity="other">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Відмінити"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Підготовка до копіювання…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Підготовка до переміщення…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 008366e..0c12aa1 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز منتقل کی جا رہی ہیں۔</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل منتقل کی جا رہی ہے۔</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں حذف ہو رہی ہیں۔</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل حذف ہو رہی ہے۔</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"کالعدم کریں"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"کاپی کیلئے تیار ہو رہا ہے…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"منتقلی کیلئے تیار ہو رہی ہیں…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index ad5b115..ec91885 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmoqda.</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmoqda.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl o‘chirilmoqda.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl o‘chirilmoqda.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Bekor qilish"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Ko‘chirishga tayyorgarlik…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index 6c4d2a5..a652ecc 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">Đang di chuyển <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
       <item quantity="one">Đang di chuyển <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">Xóa <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
+      <item quantity="one">Xóa <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Hoàn tác"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Đang chuẩn bị sao chép…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Đang chuẩn bị di chuyển…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index fbd11ad..b0f5480 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">正在移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
       <item quantity="one">正在移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">正在删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
+      <item quantity="one">正在删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"撤消"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"正在准备复制…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"正在准备移动…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 4970338..220b716 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">正在轉移 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
       <item quantity="one">正在轉移 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">正在刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
+      <item quantity="one">正在刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"復原"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"正在準備移動…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index 42c86dc..9c21aa5 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="other">正在移動 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
       <item quantity="one">正在移動 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="other">正在刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
+      <item quantity="one">正在刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"復原"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"準備移動…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index 3f09790..5ce9f12 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -73,6 +73,11 @@
       <item quantity="one">Ihambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
       <item quantity="other">Ihambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
     </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Isusa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+      <item quantity="other">Isusa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Hlehlisa"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Ilungiselela ukukopisha..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Ilungiselela ukuhambisa…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
index 0735ff9..6002dde 100644
--- a/packages/DocumentsUI/res/values/colors.xml
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -22,6 +22,10 @@
     <color name="material_blue_700">#ff1976d2</color>
     <color name="material_blue_500">#ff2196f3</color>
 
+    <color name="primary_dark">@*android:color/material_blue_grey_900</color>
+    <color name="primary">@*android:color/material_blue_grey_800</color>
+    <color name="accent">@*android:color/material_deep_teal_500</color>
+
     <color name="directory_background">@color/material_grey_300</color>
     <color name="item_doc_grid_background">#FFFFFFFF</color>
     <color name="item_doc_grid_protect_background">#88000000</color>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index f6c4628..22add98 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -17,15 +17,17 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
     <style name="DocumentsBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar" />
+    <style name="ActionBarTheme" parent="@*android:style/ThemeOverlay.Material.Dark.ActionBar" />
+    <style name="ActionBarPopupTheme" parent="@*android:style/ThemeOverlay.Material.Light" />
 
     <style name="DocumentsTheme" parent="@style/DocumentsBaseTheme">
         <item name="actionBarWidgetTheme">@null</item>
-        <item name="actionBarTheme">@*android:style/ThemeOverlay.Material.Dark.ActionBar</item>
-        <item name="actionBarPopupTheme">@*android:style/ThemeOverlay.Material.Light</item>
+        <item name="actionBarTheme">@style/ActionBarTheme</item>
+        <item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
 
-        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_900</item>
-        <item name="android:colorPrimary">@*android:color/material_blue_grey_800</item>
-        <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
+        <item name="android:colorPrimaryDark">@color/primary_dark</item>
+        <item name="android:colorPrimary">@color/primary</item>
+        <item name="android:colorAccent">@color/accent</item>
 
         <item name="android:listDivider">@*android:drawable/list_divider_material</item>
 
@@ -39,8 +41,8 @@
 
     <style name="DocumentsBaseTheme.FullScreen" parent="@style/Theme.AppCompat.Light.DarkActionBar">
         <item name="actionBarWidgetTheme">@null</item>
-        <item name="actionBarTheme">@*android:style/ThemeOverlay.Material.Dark.ActionBar</item>
-        <item name="actionBarPopupTheme">@*android:style/ThemeOverlay.Material.Light</item>
+        <item name="actionBarTheme">@style/ActionBarTheme</item>
+        <item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
 
         <item name="android:listDivider">@*android:drawable/list_divider_material</item>
 
@@ -52,9 +54,9 @@
     </style>
 
     <style name="DocumentsNonDialogTheme" parent="@style/DocumentsBaseTheme.FullScreen">
-        <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_900</item>
-        <item name="android:colorPrimary">@*android:color/material_blue_grey_800</item>
-        <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
+        <item name="android:colorPrimaryDark">@color/primary_dark</item>
+        <item name="android:colorPrimary">@color/primary</item>
+        <item name="android:colorAccent">@color/accent</item>
     </style>
 
     <style name="ActionModeStyle" parent="@android:style/Widget.Material.Light.ActionMode">
@@ -66,7 +68,7 @@
     </style>
 
     <style name="FilesTheme" parent="@style/DocumentsBaseTheme.FullScreen">
-        <item name="android:colorPrimaryDark">@color/status_bar_background</item>
+        <item name="android:colorPrimaryDark">@color/material_blue_700</item>
         <item name="android:colorPrimary">@color/material_blue_500</item>
         <item name="android:colorAccent">@color/material_blue_700</item>
         <item name="android:actionModeStyle">@style/ActionModeStyle</item>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index b7a3e4b..edf829d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -86,6 +86,7 @@
 import android.view.View;
 import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -1459,7 +1460,7 @@
                     return true;
 
                 case DragEvent.ACTION_DROP:
-                    int dstPosition = mRecView.getChildAdapterPosition(v);
+                    int dstPosition = mRecView.getChildAdapterPosition(getContainingItemView(v));
                     DocumentInfo dstDir = null;
                     if (dstPosition != android.widget.AdapterView.INVALID_POSITION) {
                         Cursor dstCursor = mModel.getItem(dstPosition);
@@ -1474,6 +1475,19 @@
         }
     };
 
+    private View getContainingItemView(View view) {
+        while (true) {
+            if (view.getLayoutParams() instanceof RecyclerView.LayoutParams) {
+                return view;
+            }
+            ViewParent parent = view.getParent();
+            if (parent == null || !(parent instanceof View)) {
+                return null;
+            }
+            view = (View) parent;
+        }
+    }
+
     private View.OnLongClickListener mLongClickListener = new View.OnLongClickListener() {
         @Override
         public boolean onLongClick(View v) {
@@ -1492,7 +1506,7 @@
     };
 
     private List<DocumentInfo> getDraggableDocuments(View currentItemView) {
-        int position = mRecView.getChildAdapterPosition(currentItemView);
+        int position = mRecView.getChildAdapterPosition(getContainingItemView(currentItemView));
         if (position == android.widget.AdapterView.INVALID_POSITION) {
             return Collections.EMPTY_LIST;
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Events.java b/packages/DocumentsUI/src/com/android/documentsui/Events.java
index 025b94f..d4c3ba3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Events.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Events.java
@@ -16,8 +16,11 @@
 
 package com.android.documentsui;
 
+import android.graphics.Point;
+import android.support.v7.widget.RecyclerView;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.View;
 
 /**
  * Utility code for dealing with MotionEvents.
@@ -54,6 +57,20 @@
     }
 
     /**
+     * Returns true if event was triggered by a finger or stylus touch.
+     */
+    static boolean isActionDown(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+    }
+
+    /**
+     * Returns true if event was triggered by a finger or stylus touch.
+     */
+    static boolean isActionUp(MotionEvent e) {
+        return e.getActionMasked() == MotionEvent.ACTION_UP;
+    }
+
+    /**
      * Returns true if the shift is pressed.
      */
     boolean isShiftPressed(MotionEvent e) {
@@ -66,4 +83,106 @@
     static boolean hasShiftBit(int metaState) {
         return (metaState & KeyEvent.META_SHIFT_ON) != 0;
     }
+
+    /**
+     * A facade over MotionEvent primarily designed to permit for unit testing
+     * of related code.
+     */
+    interface InputEvent {
+        boolean isMouseEvent();
+        boolean isPrimaryButtonPressed();
+        boolean isSecondaryButtonPressed();
+        boolean isShiftKeyDown();
+
+        /** Returns true if the action is the initial press of a mouse or touch. */
+        boolean isActionDown();
+
+        /** Returns true if the action is the final release of a mouse or touch. */
+        boolean isActionUp();
+
+        Point getOrigin();
+
+        /** Returns true if the there is an item under the finger/cursor. */
+        boolean isOverItem();
+
+        /** Returns the adapter position of the item under the finger/cursor. */
+        int getItemPosition();
+    }
+
+    static final class MotionInputEvent implements InputEvent {
+        private final MotionEvent mEvent;
+        private final RecyclerView mView;
+        private final int mPosition;
+
+        public MotionInputEvent(MotionEvent event, RecyclerView view) {
+            mEvent = event;
+            mView = view;
+            View child = mView.findChildViewUnder(mEvent.getX(), mEvent.getY());
+            mPosition = (child != null)
+                    ? mView.getChildAdapterPosition(child)
+                    : RecyclerView.NO_POSITION;
+        }
+
+        @Override
+        public boolean isMouseEvent() {
+            return Events.isMouseEvent(mEvent);
+        }
+
+        @Override
+        public boolean isPrimaryButtonPressed() {
+            return mEvent.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
+        }
+
+        @Override
+        public boolean isSecondaryButtonPressed() {
+            return mEvent.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
+        }
+
+        @Override
+        public boolean isShiftKeyDown() {
+            return Events.hasShiftBit(mEvent.getMetaState());
+        }
+
+        @Override
+        public boolean isActionDown() {
+            return mEvent.getActionMasked() == MotionEvent.ACTION_DOWN;
+        }
+
+        @Override
+        public boolean isActionUp() {
+            return mEvent.getActionMasked() == MotionEvent.ACTION_UP;
+        }
+
+        @Override
+        public Point getOrigin() {
+            return new Point((int) mEvent.getX(), (int) mEvent.getY());
+        }
+
+        @Override
+        public boolean isOverItem() {
+            return getItemPosition() != RecyclerView.NO_POSITION;
+        }
+
+        @Override
+        public int getItemPosition() {
+            return mPosition;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("MotionInputEvent {")
+                    .append("isMouseEvent=").append(isMouseEvent())
+                    .append(" isPrimaryButtonPressed=").append(isPrimaryButtonPressed())
+                    .append(" isSecondaryButtonPressed=").append(isSecondaryButtonPressed())
+                    .append(" isShiftKeyDown=").append(isShiftKeyDown())
+                    .append(" isActionDown=").append(isActionDown())
+                    .append(" isActionUp=").append(isActionUp())
+                    .append(" getOrigin=").append(getOrigin())
+                    .append(" isOverItem=").append(isOverItem())
+                    .append(" getItemPosition=").append(getItemPosition())
+                    .append("}")
+                    .toString();
+        }
+    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
index 4284f6f..f9f308d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
@@ -16,11 +16,16 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.Events.isMouseEvent;
+import static com.android.documentsui.Shared.DEBUG;
 import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.Adapter;
@@ -36,10 +41,9 @@
 import android.view.GestureDetector.OnGestureListener;
 import android.view.MotionEvent;
 import android.view.View;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.VisibleForTesting;
+
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.Events.MotionInputEvent;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -59,7 +63,6 @@
     public static final int MODE_SINGLE = 1;
 
     private static final String TAG = "MultiSelectManager";
-    private static final boolean DEBUG = false;
 
     private final Selection mSelection = new Selection();
 
@@ -72,7 +75,8 @@
     private Adapter<?> mAdapter;
     private MultiSelectHelper mHelper;
     private boolean mSingleSelect;
-    private BandSelectManager mBandSelectManager;
+
+    @Nullable private BandSelectManager mBandManager;
 
     /**
      * @param recyclerView
@@ -89,17 +93,21 @@
                 new RuntimeRecyclerViewHelper(recyclerView),
                 mode);
 
-        mBandSelectManager = new BandSelectManager((RuntimeRecyclerViewHelper) mHelper);
+        if (mode == MODE_MULTIPLE) {
+            mBandManager = new BandSelectManager((RuntimeRecyclerViewHelper) mHelper);
+        }
 
         GestureDetector.SimpleOnGestureListener listener =
                 new GestureDetector.SimpleOnGestureListener() {
                     @Override
                     public boolean onSingleTapUp(MotionEvent e) {
-                        return MultiSelectManager.this.onSingleTapUp(e);
+                        return MultiSelectManager.this.onSingleTapUp(
+                                new MotionInputEvent(e, recyclerView));
                     }
                     @Override
                     public void onLongPress(MotionEvent e) {
-                        MultiSelectManager.this.onLongPress(e);
+                        MultiSelectManager.this.onLongPress(
+                                new MotionInputEvent(e, recyclerView));
                     }
                 };
 
@@ -112,17 +120,44 @@
 
         recyclerView.addOnItemTouchListener(
                 new RecyclerView.OnItemTouchListener() {
+                    @Override
                     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                         detector.onTouchEvent(e);
 
-                        // Only intercept the event if it was a mouse-based band selection.
-                        return isMouseEvent(e) && (mBandSelectManager.mIsActive ||
-                                e.getActionMasked() != MotionEvent.ACTION_UP);
+                        if (mBandManager == null) {
+                            return false;
+                        }
+
+                        // b/23793622 notes the fact that we *never* receiver ACTION_DOWN
+                        // events in onTouchEvent. Where it not for this issue, we'd
+                        // push start handling down into handleInputEvent.
+                        if (mBandManager.shouldStart(e)) {
+                            // endBandSelect is handled in handleInputEvent.
+                            mBandManager.startBandSelect(
+                                    new Point((int) e.getX(), (int) e.getY()));
+                        } else if (mBandManager.isActive()
+                                && Events.isMouseEvent(e)
+                                && Events.isActionUp(e)) {
+                            // Same issue here w b/23793622. The ACTION_UP event
+                            // is only evert dispatched to onTouchEvent when
+                            // there is some associated motion. If a user taps
+                            // mouse, but doesn't move, then band select gets
+                            // started BUT not ended. Causing phantom
+                            // bands to appear when the user later clicks to start
+                            // band select.
+                            mBandManager.handleInputEvent(
+                                    new MotionInputEvent(e, recyclerView));
+                        }
+
+                        return mBandManager.isActive();
                     }
+
+                    @Override
                     public void onTouchEvent(RecyclerView rv, MotionEvent e) {
-                        checkState(isMouseEvent(e));
-                        mBandSelectManager.processMotionEvent(e);
+                        mBandManager.handleInputEvent(
+                                new MotionInputEvent(e, recyclerView));
                     }
+                    @Override
                     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
                 });
     }
@@ -251,7 +286,9 @@
     }
 
     public void handleLayoutChanged() {
-        mBandSelectManager.handleLayoutChanged();
+        if (mBandManager != null) {
+            mBandManager.handleLayoutChanged();
+        }
     }
 
     /**
@@ -275,71 +312,37 @@
         }
     }
 
-    private void onLongPress(MotionEvent e) {
+    @VisibleForTesting
+    void onLongPress(InputEvent input) {
         if (DEBUG) Log.d(TAG, "Handling long press event.");
 
-        int position = mHelper.findEventPosition(e);
-        if (position == RecyclerView.NO_POSITION) {
-            if (DEBUG) Log.i(TAG, "View is null. Cannot handle tap event.");
+        if (!input.isOverItem()) {
+            if (DEBUG) Log.i(TAG, "Cannot handle tap. No adapter position available.");
         }
 
-        onLongPress(position, e.getMetaState());
+        handleAdapterEvent(input);
     }
 
-    /**
-     * TODO: Roll this back into {@link #onLongPress(MotionEvent)} once MotionEvent
-     * can be mocked.
-     *
-     * @param position
-     * @param metaState as returned from {@link MotionEvent#getMetaState()}.
-     * @hide
-     */
     @VisibleForTesting
-    void onLongPress(int position, int metaState) {
-        if (position == RecyclerView.NO_POSITION) {
-            if (DEBUG) Log.i(TAG, "View is null. Cannot handle tap event.");
-        }
-
-        handlePositionChanged(position, metaState);
-    }
-
-    /**
-     * @param e
-     * @return true if the event was consumed.
-     */
-    private boolean onSingleTapUp(MotionEvent e) {
-        if (DEBUG) Log.d(TAG, "Handling tap event.");
-        return onSingleTapUp(mHelper.findEventPosition(e), e.getMetaState(), e.getToolType(0));
-    }
-
-    /**
-     * TODO: Roll this into {@link #onSingleTapUp(MotionEvent)} once MotionEvent
-     * can be mocked.
-     *
-     * @param position
-     * @param metaState as returned from {@link MotionEvent#getMetaState()}.
-     * @param toolType
-     * @return true if the event was consumed.
-     * @hide
-     */
-    @VisibleForTesting
-    boolean onSingleTapUp(int position, int metaState, int toolType) {
+    boolean onSingleTapUp(InputEvent input) {
+        if (DEBUG) Log.d(TAG, "Processing tap event.");
         if (mSelection.isEmpty()) {
             // if this is a mouse click on an item, start selection mode.
-            if (position != RecyclerView.NO_POSITION && Events.isMouseType(toolType)) {
-                toggleSelection(position);
+            // TODO:  && input.isPrimaryButtonPressed(), but it is returning false.
+            if (input.isOverItem() && input.isMouseEvent()) {
+                toggleSelection(input.getItemPosition());
             }
             return false;
         }
 
-        if (position == RecyclerView.NO_POSITION) {
-            if (DEBUG) Log.d(TAG, "View is null. Canceling selection.");
+        if (!input.isOverItem()) {
+            if (DEBUG) Log.d(TAG, "Activity has no position. Canceling selection.");
             clearSelection();
             return false;
         }
 
-        handlePositionChanged(position, metaState);
-        return false;
+        handleAdapterEvent(input);
+        return true;
     }
 
     /**
@@ -347,15 +350,15 @@
      * held down, this performs a range select; otherwise, it simply toggles the item's selection
      * state.
      */
-    private void handlePositionChanged(int position, int metaState) {
-        if (Events.hasShiftBit(metaState) && mRanger != null) {
-            mRanger.snapSelection(position);
+    private void handleAdapterEvent(InputEvent input) {
+        if (mRanger != null && input.isShiftKeyDown()) {
+            mRanger.snapSelection(input.getItemPosition());
 
             // We're being lazy here notifying even when something might not have changed.
             // To make this more correct, we'd need to update the Ranger class to return
             // information about what has changed.
             notifySelectionChanged();
-        } else if (toggleSelection(position)) {
+        } else if (toggleSelection(input.getItemPosition())) {
             notifySelectionChanged();
         }
     }
@@ -1175,12 +1178,12 @@
         private static final int NOT_SET = -1;
 
         private final BandManagerHelper mHelper;
+        private final Runnable mModelBuilder;
 
-        private boolean mIsActive;
-        private Point mOrigin;
-        private Point mPointer;
-        private Rect mBounds;
-        private BandSelectModel mModel;
+        @Nullable private Rect mBounds;
+        @Nullable private Point mCurrentPosition;
+        @Nullable private Point mOrigin;
+        @Nullable private BandSelectModel mModel;
 
         // The time at which the current band selection-induced scroll began. If no scroll is in
         // progress, the value is NOT_SET.
@@ -1188,11 +1191,21 @@
         private final Runnable mViewScroller = new ViewScroller();
 
         public <T extends BandManagerHelper & BandModelHelper>
-                BandSelectManager(T helper) {
+                BandSelectManager(final T helper) {
             mHelper = helper;
             mHelper.addOnScrollListener(this);
-            mModel = new BandSelectModel(helper);
-            mModel.addOnSelectionChangedListener(this);
+
+            mModelBuilder = new Runnable() {
+                @Override
+                public void run() {
+                    mModel = new BandSelectModel(helper);
+                    mModel.addOnSelectionChangedListener(BandSelectManager.this);
+                }
+            };
+        }
+
+        private boolean isActive() {
+            return mModel != null;
         }
 
         /**
@@ -1200,39 +1213,48 @@
          * a new model which will track the new layout.
          */
         public void handleLayoutChanged() {
-            mModel.removeOnSelectionChangedListener(this);
-            mModel.stopListening();
+            if (mModel != null) {
+                mModel.removeOnSelectionChangedListener(this);
+                mModel.stopListening();
 
-            mModel = new BandSelectModel((RuntimeRecyclerViewHelper) mHelper);
-            mModel.addOnSelectionChangedListener(this);
+                // build a new model, all fresh and happy.
+                mModelBuilder.run();
+            }
+        }
+
+        boolean shouldStart(MotionEvent e) {
+            return !isActive()
+                    && Events.isMouseEvent(e)  // a mouse
+                    && Events.isActionDown(e)  // the initial button press
+                    && mHelper.findEventPosition(e) == RecyclerView.NO_ID;  // in empty space
+        }
+
+        boolean shouldStop(InputEvent input) {
+            return isActive()
+                    && input.isMouseEvent()
+                    && input.isActionUp();
         }
 
         /**
          * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
-         * @param e
+         * @param input
          */
-        private void processMotionEvent(MotionEvent e) {
-            if (!isMouseEvent(e)) {
-                return;
-            }
+        private void handleInputEvent(InputEvent input) {
+            checkArgument(input.isMouseEvent());
 
-            if (mIsActive && e.getActionMasked() == MotionEvent.ACTION_UP) {
+            if (shouldStop(input)) {
                 endBandSelect();
                 return;
             }
 
-            mPointer = new Point((int) e.getX(), (int) e.getY());
-            if (!mIsActive) {
-                // Only start a band select if the pointer is in margins between items, not
-                // actually within an item's bounds.
-                if (mHelper.findEventPosition(e) != RecyclerView.NO_POSITION) {
-                    return;
-                }
-                startBandSelect();
-            } else {
-                mModel.resizeSelection(mPointer);
+            // We shouldn't get any events in this method when band select is not active,
+            // but it turns some guests show up late to the party.
+            if (!isActive()) {
+                return;
             }
 
+            mCurrentPosition = input.getOrigin();
+            mModel.resizeSelection(input.getOrigin());
             scrollViewIfNecessary();
             resizeBandSelectRectangle();
         }
@@ -1240,12 +1262,11 @@
         /**
          * Starts band select by adding the drawable to the RecyclerView's overlay.
          */
-        private void startBandSelect() {
-            if (DEBUG) {
-                Log.d(TAG, "Starting band select from (" + mPointer.x + "," + mPointer.y + ").");
-            }
-            mIsActive = true;
-            mOrigin = new Point(mPointer.x, mPointer.y);
+        private void startBandSelect(Point origin) {
+            if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
+
+            mOrigin = origin;
+            mModelBuilder.run();  // Creates a new selection model.
             mModel.startSelection(mOrigin);
         }
 
@@ -1263,10 +1284,10 @@
          * two opposite corners of the selection.
          */
         private void resizeBandSelectRectangle() {
-            mBounds = new Rect(Math.min(mOrigin.x, mPointer.x),
-                    Math.min(mOrigin.y, mPointer.y),
-                    Math.max(mOrigin.x, mPointer.x),
-                    Math.max(mOrigin.y, mPointer.y));
+            mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
+                    Math.min(mOrigin.y, mCurrentPosition.y),
+                    Math.max(mOrigin.x, mCurrentPosition.x),
+                    Math.max(mOrigin.y, mCurrentPosition.y));
             mHelper.drawBand(mBounds);
         }
 
@@ -1275,14 +1296,20 @@
          */
         private void endBandSelect() {
             if (DEBUG) Log.d(TAG, "Ending band select.");
-            mIsActive = false;
+
             mHelper.hideBand();
             mSelection.applyProvisionalSelection();
             mModel.endSelection();
             int firstSelected = mModel.getPositionNearestOrigin();
-            if (firstSelected != BandSelectModel.NOT_SET) {
+            if (!mSelection.contains(firstSelected)) {
+                Log.w(TAG, "First selected by band is NOT in selection!");
+                // Sadly this is really happening. Need to figure out what's going on.
+            } else if (firstSelected != BandSelectModel.NOT_SET) {
                 setSelectionFocusBegin(firstSelected);
             }
+
+            mModel = null;
+            mOrigin = null;
         }
 
         @Override
@@ -1311,13 +1338,13 @@
                 // that one additional pixel is added here so that the view still scrolls when the
                 // pointer is exactly at the top or bottom.
                 int pixelsPastView = 0;
-                if (mPointer.y <= 0) {
-                    pixelsPastView = mPointer.y - 1;
-                } else if (mPointer.y >= mHelper.getHeight() - 1) {
-                    pixelsPastView = mPointer.y - mHelper.getHeight() + 1;
+                if (mCurrentPosition.y <= 0) {
+                    pixelsPastView = mCurrentPosition.y - 1;
+                } else if (mCurrentPosition.y >= mHelper.getHeight() - 1) {
+                    pixelsPastView = mCurrentPosition.y - mHelper.getHeight() + 1;
                 }
 
-                if (!mIsActive || pixelsPastView == 0) {
+                if (!isActive() || pixelsPastView == 0) {
                     // If band selection is inactive, or if it is active but not at the edge of the
                     // view, no scrolling is necessary.
                     mScrollStartTime = NOT_SET;
@@ -1403,7 +1430,7 @@
 
         @Override
         public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-            if (!mIsActive) {
+            if (!isActive()) {
                 return;
             }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index 2bf0562..0c1ebc1 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -22,6 +22,7 @@
  * @hide
  */
 public final class Shared {
+    public static final boolean DEBUG = false;
     public static final String TAG = "Documents";
 
     /**
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java
index b82251c..337064c 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java
@@ -16,11 +16,11 @@
 
 package com.android.documentsui;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.support.v7.widget.RecyclerView;
 import android.util.SparseBooleanArray;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -52,7 +52,6 @@
     private MultiSelectManager mManager;
     private TestAdapter mAdapter;
     private TestCallback mCallback;
-
     private EventHelper mEventHelper;
 
     @Before
@@ -72,14 +71,14 @@
 
     @Test
     public void mouseClick_ShiftClickExtendsSelection() {
-        click(7);
+        longPress(7);
         shiftClick(11);
         assertRangeSelection(7, 11);
     }
 
     @Test
     public void mouseClick_NoPosition_ClearsSelection() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         click(11);
         click(RecyclerView.NO_POSITION);
         assertSelection();
@@ -95,27 +94,27 @@
 
     @Test
     public void longPress_StartsSelectionMode() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         assertSelection(7);
     }
 
     @Test
     public void longPress_SecondPressExtendsSelection() {
-        mManager.onLongPress(7, 0);
-        mManager.onLongPress(99, 0);
+        longPress(7);
+        longPress(99);
         assertSelection(7, 99);
     }
 
     @Test
     public void singleTapUp_UnselectsSelectedItem() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         tap(7);
         assertSelection();
     }
 
     @Test
     public void singleTapUp_NoPosition_ClearsSelection() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         tap(11);
         tap(RecyclerView.NO_POSITION);
         assertSelection();
@@ -123,7 +122,7 @@
 
     @Test
     public void singleTapUp_ExtendsSelection() {
-        mManager.onLongPress(99, 0);
+        longPress(99);
         tap(7);
         tap(13);
         tap(129899);
@@ -132,21 +131,21 @@
 
     @Test
     public void singleTapUp_ShiftCreatesRangeSelection() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         shiftTap(17);
         assertRangeSelection(7, 17);
     }
 
     @Test
     public void singleTapUp_ShiftCreatesRangeSeletion_Backwards() {
-        mManager.onLongPress(17, 0);
+        longPress(17);
         shiftTap(7);
         assertRangeSelection(7, 17);
     }
 
     @Test
     public void singleTapUp_SecondShiftClickExtendsSelection() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         shiftTap(11);
         shiftTap(17);
         assertRangeSelection(7, 17);
@@ -154,7 +153,7 @@
 
     @Test
     public void singleTapUp_MultipleContiguousRangesSelected() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         shiftTap(11);
         tap(20);
         shiftTap(25);
@@ -165,7 +164,7 @@
 
     @Test
     public void singleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         shiftTap(17);
         shiftTap(10);
         assertRangeSelection(7, 10);
@@ -173,7 +172,7 @@
 
     @Test
     public void singleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards() {
-        mManager.onLongPress(17, 0);
+        mManager.onLongPress(TestInputEvent.tap(17));
         shiftTap(7);
         shiftTap(14);
         assertRangeSelection(14, 17);
@@ -182,7 +181,7 @@
 
     @Test
     public void singleTapUp_ShiftReversesSelectionDirection() {
-        mManager.onLongPress(7, 0);
+        longPress(7);
         shiftTap(17);
         shiftTap(0);
         assertRangeSelection(0, 7);
@@ -192,7 +191,7 @@
     public void singleSelectMode() {
         mManager = new MultiSelectManager(mAdapter, mEventHelper, MultiSelectManager.MODE_SINGLE);
         mManager.addCallback(mCallback);
-        tap(20);
+        longPress(20);
         tap(13);
         assertSelection(13);
     }
@@ -201,7 +200,7 @@
     public void singleSelectMode_ShiftTap() {
         mManager = new MultiSelectManager(mAdapter, mEventHelper, MultiSelectManager.MODE_SINGLE);
         mManager.addCallback(mCallback);
-        tap(13);
+        longPress(13);
         shiftTap(20);
         assertSelection(20);
     }
@@ -236,20 +235,24 @@
         assertSelection(2, 3, 4);
     }
 
+    private void longPress(int position) {
+        mManager.onLongPress(TestInputEvent.tap(position));
+    }
+
     private void tap(int position) {
-        mManager.onSingleTapUp(position, 0, MotionEvent.TOOL_TYPE_MOUSE);
+        mManager.onSingleTapUp(TestInputEvent.tap(position));
     }
 
     private void shiftTap(int position) {
-        mManager.onSingleTapUp(position, KeyEvent.META_SHIFT_ON, MotionEvent.TOOL_TYPE_FINGER);
+        mManager.onSingleTapUp(TestInputEvent.shiftTap(position));
     }
 
     private void click(int position) {
-        mManager.onSingleTapUp(position, 0, MotionEvent.TOOL_TYPE_MOUSE);
+        mManager.onSingleTapUp(TestInputEvent.click(position));
     }
 
     private void shiftClick(int position) {
-        mManager.onSingleTapUp(position, KeyEvent.META_SHIFT_ON, MotionEvent.TOOL_TYPE_MOUSE);
+        mManager.onSingleTapUp(TestInputEvent.shiftClick(position));
     }
 
     private void assertSelected(int... expected) {
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java b/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java
new file mode 100644
index 0000000..e83f9e0
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java
@@ -0,0 +1,90 @@
+package com.android.documentsui;
+
+import android.graphics.Point;
+import android.support.v7.widget.RecyclerView;
+
+class TestInputEvent implements Events.InputEvent {
+
+    public boolean mouseEvent;
+    public boolean primaryButtonPressed;
+    public boolean secondaryButtonPressed;
+    public boolean shiftKeyDow;
+    public boolean actionDown;
+    public boolean actionUp;
+    public Point location;
+    public int position = Integer.MIN_VALUE;
+
+    public TestInputEvent() {}
+
+    public TestInputEvent(int position) {
+        this.position = position;
+    }
+
+    @Override
+    public boolean isMouseEvent() {
+        return mouseEvent;
+    }
+
+    @Override
+    public boolean isPrimaryButtonPressed() {
+        return primaryButtonPressed;
+    }
+
+    @Override
+    public boolean isSecondaryButtonPressed() {
+        return secondaryButtonPressed;
+    }
+
+    @Override
+    public boolean isShiftKeyDown() {
+        return shiftKeyDow;
+    }
+
+    @Override
+    public boolean isActionDown() {
+        return actionDown;
+    }
+
+    @Override
+    public boolean isActionUp() {
+        return actionUp;
+    }
+
+    @Override
+    public Point getOrigin() {
+        return location;
+    }
+
+    @Override
+    public boolean isOverItem() {
+        return position != Integer.MIN_VALUE && position != RecyclerView.NO_POSITION;
+    }
+
+    @Override
+    public int getItemPosition() {
+        return position;
+    }
+
+    public static TestInputEvent tap(int position) {
+        return new TestInputEvent(position);
+    }
+
+    public static TestInputEvent shiftTap(int position) {
+        TestInputEvent e = new TestInputEvent(position);
+        e.shiftKeyDow = true;
+        return e;
+    }
+
+    public static TestInputEvent click(int position) {
+        TestInputEvent e = new TestInputEvent(position);
+        e.mouseEvent = true;
+        return e;
+    }
+
+    public static TestInputEvent shiftClick(int position) {
+        TestInputEvent e = new TestInputEvent(position);
+        e.mouseEvent = true;
+        e.shiftKeyDow = true;
+        return e;
+    }
+}
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
index 502a2ed..cea4319 100644
--- a/packages/Keyguard/res/values-ja/strings.xml
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -112,7 +112,7 @@
     <string name="airplane_mode" msgid="3122107900897202805">"機内モード"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"端末を再起動するにはパターンが必要です。"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"端末を再起動するにはPINが必要です。"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"端末を再起動するにはパスワードが必要です。"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"端末を再起動した時にはパスワードが必要です。"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"セキュリティを強化するため、パターンが必要です。"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"セキュリティを強化するため、PINが必要です。"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"セキュリティを強化するため、パスワードが必要です。"</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index cfc232c..b752c9b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1348,9 +1348,7 @@
      */
     private void handleKeyguardReset() {
         if (DEBUG) Log.d(TAG, "handleKeyguardReset");
-        if (!isUnlockingWithFingerprintAllowed()) {
-            updateFingerprintListeningState();
-        }
+        updateFingerprintListeningState();
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b0429ef..e4b1ed8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -539,10 +539,10 @@
          * Otherwise, allow the connect on UUID change.
          */
         if (!mProfiles.isEmpty()
-                && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()
-                || (mConnectAttempted == 0))) {
+                && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) {
             connectWithoutResettingTimer(false);
         }
+
         dispatchAttributesChanged();
     }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 5a14967..ee296d9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -109,7 +109,7 @@
 
     static String dbNameForUser(final int userHandle) {
         // The owner gets the unadorned db name;
-        if (userHandle == UserHandle.USER_OWNER) {
+        if (userHandle == UserHandle.USER_SYSTEM) {
             return DATABASE_NAME;
         } else {
             // Place the database in the user-specific data tree so that it's
@@ -186,8 +186,8 @@
 
         createSecureTable(db);
 
-        // Only create the global table for the singleton 'owner' user
-        if (mUserHandle == UserHandle.USER_OWNER) {
+        // Only create the global table for the singleton 'owner/system' user
+        if (mUserHandle == UserHandle.USER_SYSTEM) {
             createGlobalTable(db);
         }
 
@@ -1252,7 +1252,7 @@
 
         if (upgradeVersion == 82) {
             // Move to per-user settings dbs
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
 
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
@@ -1306,7 +1306,7 @@
         }
 
         if (upgradeVersion == 84) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1331,7 +1331,7 @@
         }
 
         if (upgradeVersion == 85) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     // Fix up the migration, ignoring already-migrated elements, to snap up to
@@ -1348,7 +1348,7 @@
         }
 
         if (upgradeVersion == 86) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     String[] settingsToMove = {
@@ -1367,7 +1367,7 @@
         }
 
         if (upgradeVersion == 87) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     String[] settingsToMove = {
@@ -1386,7 +1386,7 @@
         }
 
         if (upgradeVersion == 88) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     String[] settingsToMove = {
@@ -1432,7 +1432,7 @@
         }
 
         if (upgradeVersion == 89) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     String[] prefixesToMove = {
@@ -1452,7 +1452,7 @@
         }
 
         if (upgradeVersion == 90) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     String[] systemToGlobal = {
@@ -1485,7 +1485,7 @@
         }
 
         if (upgradeVersion == 91) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     // Move ringer mode from system to global settings
@@ -1505,7 +1505,7 @@
             try {
                 stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                         + " VALUES(?,?);");
-                if (mUserHandle == UserHandle.USER_OWNER) {
+                if (mUserHandle == UserHandle.USER_SYSTEM) {
                     // consider existing primary users to have made it through user setup
                     // if the globally-scoped device-provisioned bit is set
                     // (indicating they already made it through setup as primary)
@@ -1526,7 +1526,7 @@
 
         if (upgradeVersion == 93) {
             // Redo this step, since somehow it didn't work the first time for some users
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     // Migrate now-global settings
@@ -1547,7 +1547,7 @@
 
         if (upgradeVersion == 94) {
             // Add wireless charging started sound setting
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1565,7 +1565,7 @@
         }
 
         if (upgradeVersion == 95) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 try {
                     String[] settingsToMove = { Settings.Global.BUGREPORT_IN_POWER_MENU };
@@ -1584,7 +1584,7 @@
         }
 
         if (upgradeVersion == 97) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1613,7 +1613,7 @@
 
         if (upgradeVersion == 100) {
             // note: LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1631,7 +1631,7 @@
         }
 
         if (upgradeVersion == 101) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1653,7 +1653,7 @@
             try {
                 // The INSTALL_NON_MARKET_APPS setting is becoming per-user rather
                 // than device-global.
-                if (mUserHandle == UserHandle.USER_OWNER) {
+                if (mUserHandle == UserHandle.USER_SYSTEM) {
                     // In the owner user, the global table exists so we can migrate the
                     // entry from there to the secure table, preserving its value.
                     String[] globalToSecure = {
@@ -1693,7 +1693,7 @@
         }
 
         if (upgradeVersion < 105) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1719,7 +1719,7 @@
                         + " VALUES(?,?);");
                 loadIntegerSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
                         R.integer.def_lock_screen_show_notifications);
-                if (mUserHandle == UserHandle.USER_OWNER) {
+                if (mUserHandle == UserHandle.USER_SYSTEM) {
                     final int oldShow = getIntValueFromTable(db,
                             TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
                     if (oldShow >= 0) {
@@ -1741,7 +1741,7 @@
 
         if (upgradeVersion < 107) {
             // Add trusted sound setting
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1816,7 +1816,7 @@
 
         if (upgradeVersion < 111) {
             // reset ringer mode, so it doesn't force zen mode to follow
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1833,7 +1833,7 @@
         }
 
         if (upgradeVersion < 112) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 // When device name was added, we went with Manufacturer + Model, device name should
                 // actually be Model only.
                 // Update device name to Model if it wasn't modified by user.
@@ -1874,7 +1874,7 @@
         // We skipped 114 to handle a merge conflict with the introduction of theater mode.
 
         if (upgradeVersion < 115) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -1892,7 +1892,7 @@
         }
 
         if (upgradeVersion < 116) {
-            if (mUserHandle == UserHandle.USER_OWNER) {
+            if (mUserHandle == UserHandle.USER_SYSTEM) {
                 db.beginTransaction();
                 SQLiteStatement stmt = null;
                 try {
@@ -2066,7 +2066,7 @@
                     LockPatternUtils lpu = new LockPatternUtils(mContext);
                     List<LockPatternView.Cell> cellPattern =
                             LockPatternUtils.stringToPattern(lockPattern);
-                    lpu.saveLockPattern(cellPattern, null, UserHandle.USER_OWNER);
+                    lpu.saveLockPattern(cellPattern, null, UserHandle.USER_SYSTEM);
                 } catch (IllegalArgumentException e) {
                     // Don't want corrupted lock pattern to hang the reboot process
                 }
@@ -2343,8 +2343,8 @@
     private void loadSettings(SQLiteDatabase db) {
         loadSystemSettings(db);
         loadSecureSettings(db);
-        // The global table only exists for the 'owner' user
-        if (mUserHandle == UserHandle.USER_OWNER) {
+        // The global table only exists for the 'owner/system' user
+        if (mUserHandle == UserHandle.USER_SYSTEM) {
             loadGlobalSettings(db);
         }
     }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 952b220..1d71346 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -123,7 +123,8 @@
         }
 
         if (sBroadcastOnRestore.contains(name)) {
-            oldValue = table.lookup(cr, name, UserHandle.USER_OWNER);
+            // TODO: http://b/22388012
+            oldValue = table.lookup(cr, name, UserHandle.USER_SYSTEM);
             sendBroadcast = true;
         }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 73971ad..8b1caf9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -18,7 +18,7 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
-import android.app.AppOpsManager;
+import android.app.AppGlobals;
 import android.app.backup.BackupManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentProvider;
@@ -27,6 +27,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
@@ -47,6 +48,7 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -208,13 +210,13 @@
     private volatile UserManager mUserManager;
 
     // We have to call in the package manager with no lock held,
-    private volatile PackageManager mPackageManager;
+    private volatile IPackageManager mPackageManager;
 
     @Override
     public boolean onCreate() {
         synchronized (mLock) {
-            mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-            mPackageManager = getContext().getPackageManager();
+            mUserManager = UserManager.get(getContext());
+            mPackageManager = AppGlobals.getPackageManager();
             mSettingsRegistry = new SettingsRegistry();
         }
         registerBroadcastReceivers();
@@ -496,7 +498,7 @@
     }
 
     private void dumpForUser(int userId, PrintWriter pw) {
-        if (userId == UserHandle.USER_OWNER) {
+        if (userId == UserHandle.USER_SYSTEM) {
             pw.println("GLOBAL SETTINGS (user " + userId + ")");
             Cursor globalCursor = getAllGlobalSettings(ALL_COLUMNS);
             dumpSettings(globalCursor, pw);
@@ -547,7 +549,7 @@
             @Override
             public void onReceive(Context context, Intent intent) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
-                        UserHandle.USER_OWNER);
+                        UserHandle.USER_SYSTEM);
 
                 switch (intent.getAction()) {
                     case Intent.ACTION_USER_REMOVED: {
@@ -584,7 +586,7 @@
         synchronized (mLock) {
             // Get the settings.
             SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
-                    SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+                    SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
 
             List<String> names = settingsState.getSettingNamesLocked();
 
@@ -612,7 +614,7 @@
         // Get the value.
         synchronized (mLock) {
             return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
-                    UserHandle.USER_OWNER, name);
+                    UserHandle.USER_SYSTEM, name);
         }
     }
 
@@ -656,19 +658,19 @@
                 case MUTATION_OPERATION_INSERT: {
                     return mSettingsRegistry
                             .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
-                                    UserHandle.USER_OWNER, name, value, getCallingPackage());
+                                    UserHandle.USER_SYSTEM, name, value, getCallingPackage());
                 }
 
                 case MUTATION_OPERATION_DELETE: {
                     return mSettingsRegistry.deleteSettingLocked(
                             SettingsRegistry.SETTINGS_TYPE_GLOBAL,
-                            UserHandle.USER_OWNER, name);
+                            UserHandle.USER_SYSTEM, name);
                 }
 
                 case MUTATION_OPERATION_UPDATE: {
                     return mSettingsRegistry
                             .updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
-                                    UserHandle.USER_OWNER, name, value, getCallingPackage());
+                                    UserHandle.USER_SYSTEM, name, value, getCallingPackage());
                 }
             }
         }
@@ -903,7 +905,7 @@
         }
 
         // Enforce what the calling package can mutate the system settings.
-        enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name);
+        enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name, runAsUserId);
 
         // Resolve the userId on whose behalf the call is made.
         final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId);
@@ -1001,7 +1003,7 @@
     }
 
     private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation,
-            String name) {
+            String name, int userId) {
         // System/root/shell can mutate whatever secure settings they want.
         final int callingUid = Binder.getCallingUid();
         if (callingUid == android.os.Process.SYSTEM_UID
@@ -1019,7 +1021,7 @@
                 }
 
                 // The calling package is already verified.
-                PackageInfo packageInfo = getCallingPackageInfoOrThrow();
+                PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
 
                 // Privileged apps can do whatever they want.
                 if ((packageInfo.applicationInfo.privateFlags
@@ -1039,7 +1041,7 @@
                 }
 
                 // The calling package is already verified.
-                PackageInfo packageInfo = getCallingPackageInfoOrThrow();
+                PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
 
                 // Privileged apps can do whatever they want.
                 if ((packageInfo.applicationInfo.privateFlags &
@@ -1053,17 +1055,17 @@
         }
     }
 
-    private PackageInfo getCallingPackageInfoOrThrow() {
+    private PackageInfo getCallingPackageInfoOrThrow(int userId) {
         try {
-            return mPackageManager.getPackageInfo(getCallingPackage(), 0);
-        } catch (PackageManager.NameNotFoundException e) {
+            return mPackageManager.getPackageInfo(getCallingPackage(), 0, userId);
+        } catch (RemoteException e) {
             throw new IllegalStateException("Calling package doesn't exist");
         }
     }
 
     private int getGroupParentLocked(int userId) {
         // Most frequent use case.
-        if (userId == UserHandle.USER_OWNER) {
+        if (userId == UserHandle.USER_SYSTEM) {
             return userId;
         }
         // We are in the same process with the user manager and the returned
@@ -1401,8 +1403,8 @@
             migrateLegacySettingsForUserIfNeededLocked(userId);
 
             // Ensure global settings loaded if owner.
-            if (userId == UserHandle.USER_OWNER) {
-                final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+            if (userId == UserHandle.USER_SYSTEM) {
+                final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
                 ensureSettingsStateLocked(globalKey);
             }
 
@@ -1541,7 +1543,7 @@
 
         private void migrateAllLegacySettingsIfNeeded() {
             synchronized (mLock) {
-                final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+                final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
                 File globalFile = getSettingsFile(key);
                 if (globalFile.exists()) {
                     return;
@@ -1591,7 +1593,7 @@
         private void migrateLegacySettingsForUserLocked(DatabaseHelper dbHelper,
                 SQLiteDatabase database, int userId) {
             // Move over the global settings if owner.
-            if (userId == UserHandle.USER_OWNER) {
+            if (userId == UserHandle.USER_SYSTEM) {
                 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, userId);
                 ensureSettingsStateLocked(globalKey);
                 SettingsState globalSettings = mSettingsStates.get(globalKey);
@@ -1898,7 +1900,7 @@
                 }
 
                 // Set the global settings version if owner.
-                if (mUserId == UserHandle.USER_OWNER) {
+                if (mUserId == UserHandle.USER_SYSTEM) {
                     SettingsState globalSettings = getSettingsLocked(
                             SettingsRegistry.SETTINGS_TYPE_GLOBAL, mUserId);
                     globalSettings.setVersionLocked(newVersion);
@@ -1914,7 +1916,7 @@
             }
 
             private SettingsState getGlobalSettingsLocked() {
-                return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+                return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
             }
 
             private SettingsState getSecureSettingsLocked(int userId) {
@@ -1960,7 +1962,7 @@
 
                 // v119: Reset zen + ringer mode.
                 if (currentVersion == 118) {
-                    if (userId == UserHandle.USER_OWNER) {
+                    if (userId == UserHandle.USER_SYSTEM) {
                         final SettingsState globalSettings = getGlobalSettingsLocked();
                         globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE,
                                 Integer.toString(Settings.Global.ZEN_MODE_OFF),
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
index c7cc89b..8e56f47 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
@@ -48,7 +48,7 @@
             Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE
     };
 
-    protected int mSecondaryUserId = UserHandle.USER_OWNER;
+    protected int mSecondaryUserId = UserHandle.USER_SYSTEM;
 
     @Override
     public void setContext(Context context) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java
index d581f3b..a09d5fe 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java
@@ -47,7 +47,7 @@
 
                 // Make sure the setting changed.
                 String firstValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
-                        FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+                        FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
                 assertEquals("Setting value didn't change", FAKE_SETTING_VALUE, firstValue);
 
                 // Set the setting to its second value.
@@ -56,7 +56,7 @@
 
                 // Make sure the setting changed.
                 String secondValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
-                        FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+                        FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
                 assertEquals("Setting value didn't change", FAKE_SETTING_VALUE_1, secondValue);
             }
         } finally {
@@ -86,20 +86,20 @@
             for (int i = 0; i < ITERATION_COUNT; i++) {
                 // Set the setting to its first value.
                 setStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME,
-                        FAKE_SETTING_VALUE, UserHandle.USER_OWNER);
+                        FAKE_SETTING_VALUE, UserHandle.USER_SYSTEM);
 
                 // Make sure the setting changed.
                 String firstValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
-                        FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+                        FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
                 assertEquals("Setting value didn't change", FAKE_SETTING_VALUE, firstValue);
 
                 // Set the setting to its second value.
                 setStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME,
-                        FAKE_SETTING_VALUE_1, UserHandle.USER_OWNER);
+                        FAKE_SETTING_VALUE_1, UserHandle.USER_SYSTEM);
 
                 // Make sure the setting changed.
                 String secondValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
-                        FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+                        FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
                 assertEquals("Setting value didn't change", FAKE_SETTING_VALUE_1, secondValue);
             }
         } finally {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index ad56b9d..8ca1b46 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -46,40 +46,40 @@
 
     private final Object mLock = new Object();
 
-    public void testSetAndGetGlobalViaFrontEndApiForOwnerUser() throws Exception {
-        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_OWNER);
+    public void testSetAndGetGlobalViaFrontEndApiForSystemUser() throws Exception {
+        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
     }
 
-    public void testSetAndGetGlobalViaFrontEndApiForNonOwnerUser() throws Exception {
-        if (mSecondaryUserId == UserHandle.USER_OWNER) {
+    public void testSetAndGetGlobalViaFrontEndApiForNonSystemUser() throws Exception {
+        if (mSecondaryUserId == UserHandle.USER_SYSTEM) {
             Log.w(LOG_TAG, "No secondary user. Skipping "
-                    + "testSetAndGetGlobalViaFrontEndApiForNonOwnerUser");
+                    + "testSetAndGetGlobalViaFrontEndApiForNonSystemUser");
             return;
         }
         performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, mSecondaryUserId);
     }
 
-    public void testSetAndGetSecureViaFrontEndApiForOwnerUser() throws Exception {
-        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_OWNER);
+    public void testSetAndGetSecureViaFrontEndApiForSystemUser() throws Exception {
+        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_SYSTEM);
     }
 
-    public void testSetAndGetSecureViaFrontEndApiForNonOwnerUser() throws Exception {
-        if (mSecondaryUserId == UserHandle.USER_OWNER) {
+    public void testSetAndGetSecureViaFrontEndApiForNonSystemUser() throws Exception {
+        if (mSecondaryUserId == UserHandle.USER_SYSTEM) {
             Log.w(LOG_TAG, "No secondary user. Skipping "
-                    + "testSetAndGetSecureViaFrontEndApiForNonOwnerUser");
+                    + "testSetAndGetSecureViaFrontEndApiForNonSystemUser");
             return;
         }
         performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, mSecondaryUserId);
     }
 
-    public void testSetAndGetSystemViaFrontEndApiForOwnerUser() throws Exception {
-        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_OWNER);
+    public void testSetAndGetSystemViaFrontEndApiForSystemUser() throws Exception {
+        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_SYSTEM);
     }
 
-    public void testSetAndGetSystemViaFrontEndApiForNonOwnerUser() throws Exception {
-        if (mSecondaryUserId == UserHandle.USER_OWNER) {
+    public void testSetAndGetSystemViaFrontEndApiForNonSystemUser() throws Exception {
+        if (mSecondaryUserId == UserHandle.USER_SYSTEM) {
             Log.w(LOG_TAG, "No secondary user. Skipping "
-                    + "testSetAndGetSystemViaFrontEndApiForNonOwnerUser");
+                    + "testSetAndGetSystemViaFrontEndApiForNonSystemUser");
             return;
         }
         performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, mSecondaryUserId);
@@ -357,7 +357,7 @@
             public void run() {
                 insertStringViaProviderApi(type, name, value, withTableRowUri);
             }
-        }, type, name, value, UserHandle.USER_OWNER);
+        }, type, name, value, UserHandle.USER_SYSTEM);
     }
 
     private void setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type,
diff --git a/packages/SystemUI/res/drawable-anydpi/nav_app_divider.xml b/packages/SystemUI/res/drawable-anydpi/nav_app_divider.xml
deleted file mode 100644
index b2d988e..0000000
--- a/packages/SystemUI/res/drawable-anydpi/nav_app_divider.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="1dp"
-        android:height="24dp"
-        android:viewportWidth="1"
-        android:viewportHeight="24">
-    <path
-        android:pathData="M0,0 L1,0 L1,24 L0,24 z"
-        android:fillColor="#AAFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/navigation_bar_with_apps.xml b/packages/SystemUI/res/layout/navigation_bar_with_apps.xml
index 01c239e..ac95b5e 100644
--- a/packages/SystemUI/res/layout/navigation_bar_with_apps.xml
+++ b/packages/SystemUI/res/layout/navigation_bar_with_apps.xml
@@ -82,21 +82,6 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     />
-
-                <ImageView android:id="@+id/app_divider"
-                    android:focusable="false"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:layout_marginLeft="10dp"
-                    android:layout_marginRight="10dp"
-                    android:src="@drawable/nav_app_divider"
-                    />
-
-                <com.android.systemui.statusbar.phone.NavigationBarRecents
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    />
             </LinearLayout>
 
             <FrameLayout
@@ -248,21 +233,6 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     />
-
-                <ImageView android:id="@+id/app_divider"
-                    android:focusable="false"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:layout_marginLeft="10dp"
-                    android:layout_marginRight="10dp"
-                    android:src="@drawable/nav_app_divider"
-                    />
-
-            <com.android.systemui.statusbar.phone.NavigationBarRecents
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                />
             </LinearLayout>
 
             <FrameLayout
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index fbf0eb42..0e5532c 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -436,7 +436,7 @@
     <string name="clock_seconds" msgid="7689554147579179507">"Erakutsi erlojuko segundoak"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Erakutsi erlojuko segundoak egoera-barran. Baliteke bateria gehiago erabiltzea."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Berrantolatu ezarpen bizkorrak"</string>
-    <string name="show_brightness" msgid="6613930842805942519">"Erakutsi ezarpen bizkorren distira"</string>
-    <string name="qs_paging" msgid="7020133150248666132">"Erabili ezarpen bizkorretako orriak pasatzeko diseinu berria"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"Erakutsi distira Ezarpen bizkorretan"</string>
+    <string name="qs_paging" msgid="7020133150248666132">"Erabili orriak pasatzeko diseinu berria Ezarpen bizkorretan"</string>
     <string name="experimental" msgid="6198182315536726162">"Esperimentala"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e38501d..44058a3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -437,12 +437,8 @@
     <string name="activity_not_found" msgid="348423244327799974">"האפליקציה אינה מותקנת במכשיר"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"הצג שניות בשעון"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"הצג שניות בשעון בשורת הסטטוס. פעולה זו עשויה להשפיע על אורך חיי הסוללה."</string>
-    <!-- no translation found for qs_rearrange (8060918697551068765) -->
-    <skip />
-    <!-- no translation found for show_brightness (6613930842805942519) -->
-    <skip />
-    <!-- no translation found for qs_paging (7020133150248666132) -->
-    <skip />
-    <!-- no translation found for experimental (6198182315536726162) -->
-    <skip />
+    <string name="qs_rearrange" msgid="8060918697551068765">"סידור מחדש של הגדרות מהירות"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"הצג בהירות בהגדרות מהירות"</string>
+    <string name="qs_paging" msgid="7020133150248666132">"השתמש באפשרות הדפדוף בהגדרות המהירות"</string>
+    <string name="experimental" msgid="6198182315536726162">"ניסיוניות"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index efe699b..65f91a2 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -436,7 +436,7 @@
     <string name="clock_seconds" msgid="7689554147579179507">"Сааттын секунддары көрсөтүлсүн"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Ыкчам жөндөөлөрдү кайра коюу"</string>
-    <string name="show_brightness" msgid="6613930842805942519">"Ыкчам жөндөөлөрдөн жарыктыгын көрсөтүү"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"Ыкчам жөндөөлөрдөн жарык деңгээлин көрсөтүү"</string>
     <string name="qs_paging" msgid="7020133150248666132">"Ыкчам жөндөөлөрдөн баракты номерлөөнү колдонуу"</string>
     <string name="experimental" msgid="6198182315536726162">"Сынамык"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index fe50f90..2b9d953 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -435,8 +435,8 @@
     <string name="activity_not_found" msgid="348423244327799974">"अनुप्रयोग आपल्या डिव्हाइसवर स्थापित केलेला नाही"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"घड्‍याळ सेकंद दर्शवा"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बारमध्‍ये घड्‍याळ सेकंद दर्शवा. कदाचित बॅटरी आयुष्‍य प्रभावित होऊ शकते."</string>
-    <string name="qs_rearrange" msgid="8060918697551068765">"दृत सेटिंग्जची पुनर्रचना करा"</string>
-    <string name="show_brightness" msgid="6613930842805942519">"दृत सेटिंग्जमध्‍ये चमक दर्शवा"</string>
+    <string name="qs_rearrange" msgid="8060918697551068765">"द्रुत सेटिंग्जची पुनर्रचना करा"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिंग्जमध्‍ये चमक दर्शवा"</string>
     <string name="qs_paging" msgid="7020133150248666132">"द्रुत सेटिंग्जमध्ये लिखाण वापरा"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रायोगिक"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index be42e8a..12609c7 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -435,7 +435,7 @@
     <string name="activity_not_found" msgid="348423244327799974">"A aplicação não está instalada no dispositivo"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de estado. Pode afetar a autonomia da bateria."</string>
-    <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar Definições rápidas"</string>
+    <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar as Definições rápidas"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar luminosidade nas Definições rápidas"</string>
     <string name="qs_paging" msgid="7020133150248666132">"Utilizar paginação nas Definições rápidas"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 118c4b8..04ec78b 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -437,6 +437,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Holat panelida soat soniyalari ko‘rsatilsin. Bu batareya resursiga ta’sir qilishi mumkin."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Tezkor sozlamalarni qayta tartiblash"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Tezkor sozlamalarda yorqinlikni ko‘rsatish"</string>
-    <string name="qs_paging" msgid="7020133150248666132">"Tezkor sozlamalarda peyjingdan foydalanish"</string>
+    <string name="qs_paging" msgid="7020133150248666132">"Tezkor sozlamalarni sahifalarga ajratish"</string>
     <string name="experimental" msgid="6198182315536726162">"Tajribaviy"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 05644e7..4d70f24 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -437,12 +437,8 @@
     <string name="activity_not_found" msgid="348423244327799974">"您的设备中未安装此应用"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"显示时钟的秒数"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"在状态栏中显示时钟的秒数。这可能会影响电池的续航时间。"</string>
-    <!-- no translation found for qs_rearrange (8060918697551068765) -->
-    <skip />
-    <!-- no translation found for show_brightness (6613930842805942519) -->
-    <skip />
-    <!-- no translation found for qs_paging (7020133150248666132) -->
-    <skip />
-    <!-- no translation found for experimental (6198182315536726162) -->
-    <skip />
+    <string name="qs_rearrange" msgid="8060918697551068765">"重新排列快速设置"</string>
+    <string name="show_brightness" msgid="6613930842805942519">"在快速设置中显示亮度栏"</string>
+    <string name="qs_paging" msgid="7020133150248666132">"在快速设置中使用分页功能"</string>
+    <string name="experimental" msgid="6198182315536726162">"实验性"</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6f49fd6..0be3069 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1051,6 +1051,7 @@
                 // Without this, settings is not enabled until the lock screen first appears
                 setShowingLocked(false);
                 hideLocked();
+                mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
                 return;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
index b701e0b..300ea2a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
@@ -197,6 +197,7 @@
                 break;
             case PLACE_FULL:
                 // Nothing to change.
+                mBounds[0] = null;
                 break;
         }
 
@@ -213,10 +214,13 @@
         dismiss();
         mRecentsActivity.dismissRecentsToHomeWithoutTransitionAnimation();
 
-        // Resize all tasks beginning from the "oldest" one.
-        for (int i = additionalTasks; i >= 0; --i) {
-            if (mTasks[i] != null) {
-               mSsp.resizeTask(mTasks[i].key.id, mBounds[i]);
+        // In debug mode, we force all task to be resizeable regardless of the
+        // current app configuration.
+        if (RecentsConfiguration.getInstance().multiStackEnabled) {
+            for (int i = additionalTasks; i >= 0; --i) {
+                if (mTasks[i] != null) {
+                    mSsp.setTaskResizeable(mTasks[i].key.id);
+                }
             }
         }
 
@@ -224,7 +228,7 @@
         // the focus ends on the selected one.
         for (int i = additionalTasks; i >= 0; --i) {
             if (mTasks[i] != null) {
-                mRecentsView.launchTask(mTasks[i]);
+                mRecentsView.launchTask(mTasks[i], mBounds[i]);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 89aeabc..bead1b0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -271,17 +271,12 @@
         return null;
     }
 
-    /** Resize a given task. */
-    public void resizeTask(int taskId, Rect bounds) {
+    /** Allow a task to resize. */
+    public void setTaskResizeable(int taskId) {
         if (mIam == null) return;
 
         try {
-            if (RecentsConfiguration.getInstance().multiStackEnabled) {
-                // In debug mode, we force all task to be resizeable regardless of the
-                // current app configuration.
-                mIam.setTaskResizeable(taskId, true);
-            }
-            mIam.resizeTask(taskId, bounds);
+            mIam.setTaskResizeable(taskId, true);
         } catch (RemoteException e) {
             e.printStackTrace();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 00ac5f9..651b29a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -165,7 +165,7 @@
 
     /** Gets the next task in the stack - or if the last - the top task */
     public Task getNextTaskOrTopTask(Task taskToSearch) {
-        Task returnTask = null; 
+        Task returnTask = null;
         boolean found = false;
         List<TaskStackView> stackViews = getTaskStackViews();
         int stackCount = stackViews.size();
@@ -203,7 +203,7 @@
                 TaskView tv = taskViews.get(j);
                 Task task = tv.getTask();
                 if (tv.isFocusedTask()) {
-                    onTaskViewClicked(stackView, tv, stack, task, false);
+                    onTaskViewClicked(stackView, tv, stack, task, false, false, null);
                     return true;
                 }
             }
@@ -212,7 +212,7 @@
     }
 
     /** Launches a given task. */
-    public boolean launchTask(Task task) {
+    public boolean launchTask(Task task, Rect taskBounds) {
         // Get the first stack view
         List<TaskStackView> stackViews = getTaskStackViews();
         int stackCount = stackViews.size();
@@ -225,7 +225,7 @@
             for (int j = 0; j < taskViewCount; j++) {
                 TaskView tv = taskViews.get(j);
                 if (tv.getTask() == task) {
-                    onTaskViewClicked(stackView, tv, stack, task, false);
+                    onTaskViewClicked(stackView, tv, stack, task, false, true, taskBounds);
                     return true;
                 }
             }
@@ -250,7 +250,7 @@
                     if (tasks.get(j).isLaunchTarget) {
                         Task task = tasks.get(j);
                         TaskView tv = stackView.getChildViewForTask(task);
-                        onTaskViewClicked(stackView, tv, stack, task, false);
+                        onTaskViewClicked(stackView, tv, stack, task, false, false, null);
                         return true;
                     }
                 }
@@ -373,7 +373,7 @@
                     searchBarSpaceBounds.right, searchBarSpaceBounds.bottom);
         }
 
-        // Layout each TaskStackView with the full width and height of the window since the 
+        // Layout each TaskStackView with the full width and height of the window since the
         // transition view is a child of that stack view
         List<TaskStackView> stackViews = getTaskStackViews();
         int stackCount = stackViews.size();
@@ -604,7 +604,8 @@
 
     @Override
     public void onTaskViewClicked(final TaskStackView stackView, final TaskView tv,
-                                  final TaskStack stack, final Task task, final boolean lockToTask) {
+                                  final TaskStack stack, final Task task, final boolean lockToTask,
+                                  final boolean boundsValid, final Rect bounds) {
 
         // Notify any callbacks of the launching of a new task
         if (mCb != null) {
@@ -632,9 +633,9 @@
         final SystemServicesProxy ssp =
                 RecentsTaskLoader.getInstance().getSystemServicesProxy();
         ActivityOptions opts = null;
+        ActivityOptions.OnAnimationStartedListener animStartedListener = null;
         if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
                 task.thumbnail.getHeight() > 0) {
-            ActivityOptions.OnAnimationStartedListener animStartedListener = null;
             if (lockToTask) {
                 animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
                     boolean mTriggered = false;
@@ -665,9 +666,14 @@
                         offsetX, offsetY, transform.rect.width(), transform.rect.height(),
                         sourceView.getHandler(), animStartedListener);
             }
+        } else {
+            opts = ActivityOptions.makeBasic();
         }
-
+        if (boundsValid) {
+            opts.setBounds(bounds);
+        }
         final ActivityOptions launchOpts = opts;
+        final boolean screenPinningRequested = (animStartedListener == null) && lockToTask;
         final Runnable launchRunnable = new Runnable() {
             @Override
             public void run() {
@@ -677,7 +683,7 @@
                 } else {
                     if (ssp.startActivityFromRecents(getContext(), task.key.id,
                             task.activityLabel, launchOpts)) {
-                        if (launchOpts == null && lockToTask) {
+                        if (screenPinningRequested) {
                             mCb.onScreenPinningRequest();
                         }
                     } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 0068f84..4e82c8a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -59,7 +59,7 @@
     /** The TaskView callbacks */
     interface TaskStackViewCallbacks {
         public void onTaskViewClicked(TaskStackView stackView, TaskView tv, TaskStack stack, Task t,
-                                      boolean lockToTask);
+                                      boolean lockToTask, boolean boundsValid, Rect bounds);
         public void onTaskViewAppInfoClicked(Task t);
         public void onTaskViewDismissed(Task t);
         public void onAllTaskViewsDismissed(ArrayList<Task> removedTasks);
@@ -1377,7 +1377,7 @@
         mUIDozeTrigger.stopDozing();
 
         if (mCb != null) {
-            mCb.onTaskViewClicked(this, tv, mStack, task, lockToTask);
+            mCb.onTaskViewClicked(this, tv, mStack, task, lockToTask, false, null);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java
new file mode 100644
index 0000000..2c6987c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java
@@ -0,0 +1,56 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.app.ActivityManager.RecentTaskInfo;
+
+import java.util.ArrayList;
+
+/**
+ * Data associated with an app button.
+ */
+class AppButtonData {
+    public final AppInfo appInfo;
+    public boolean pinned;
+    // Recent tasks for this app, sorted by lastActiveTime, descending.
+    public ArrayList<RecentTaskInfo> tasks;
+
+    public AppButtonData(AppInfo appInfo, boolean pinned) {
+        this.appInfo = appInfo;
+        this.pinned = pinned;
+    }
+
+    /**
+     * Returns true if the button contains no useful information and should be removed.
+     */
+    public boolean isEmpty() {
+        return !pinned && (tasks == null || tasks.isEmpty());
+    }
+
+    public void addTask(RecentTaskInfo task) {
+        if (tasks == null) {
+            tasks = new ArrayList<RecentTaskInfo>();
+        }
+        tasks.add(task);
+    }
+
+    public void clearTasks() {
+        if (tasks != null) {
+            tasks.clear();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
index e34c821..8f0b532 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
@@ -39,4 +39,16 @@
     public UserHandle getUser() {
         return mUser;
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AppInfo other = (AppInfo) obj;
+        return mComponentName.equals(other.mComponentName) && mUser.equals(other.mUser);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
index f46d1a6..d2bec7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
@@ -20,6 +20,12 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.RemoteException;
@@ -30,7 +36,7 @@
  * Retrieves the icon for an activity and sets it as the Drawable on an ImageView. The ImageView
  * is hidden if the activity isn't recognized or if there is no icon.
  */
-class GetActivityIconTask extends AsyncTask<AppInfo, Void, Drawable> {
+class GetActivityIconTask extends AsyncTask<AppButtonData, Void, Drawable> {
     private final static String TAG = "GetActivityIconTask";
 
     private final PackageManager mPackageManager;
@@ -44,11 +50,12 @@
     }
 
     @Override
-    protected Drawable doInBackground(AppInfo... params) {
+    protected Drawable doInBackground(AppButtonData... params) {
         if (params.length != 1) {
             throw new IllegalArgumentException("Expected one parameter");
         }
-        AppInfo appInfo = params[0];
+        AppButtonData buttonData = params[0];
+        AppInfo appInfo = buttonData.appInfo;
         try {
             IPackageManager mPM = AppGlobals.getPackageManager();
             ActivityInfo ai = mPM.getActivityInfo(
@@ -62,7 +69,37 @@
             }
 
             Drawable unbadgedIcon = ai.loadIcon(mPackageManager);
-            return mPackageManager.getUserBadgedIcon(unbadgedIcon, appInfo.getUser());
+            Drawable badgedIcon =
+                    mPackageManager.getUserBadgedIcon(unbadgedIcon, appInfo.getUser());
+
+            if (NavigationBarApps.DEBUG) {
+                // Draw pinned indicator and number of running tasks.
+                Bitmap bitmap = Bitmap.createBitmap(
+                        badgedIcon.getIntrinsicWidth(),
+                        badgedIcon.getIntrinsicHeight(),
+                        Bitmap.Config.ARGB_8888);
+                Canvas canvas = new Canvas(bitmap);
+                badgedIcon.setBounds(
+                        0, 0, badgedIcon.getIntrinsicWidth(), badgedIcon.getIntrinsicHeight());
+                badgedIcon.draw(canvas);
+                Paint paint = new Paint();
+                paint.setStyle(Paint.Style.FILL);
+                if (buttonData.pinned) {
+                    paint.setColor(Color.WHITE);
+                    canvas.drawCircle(10, 10, 10, paint);
+                }
+                if (buttonData.tasks != null && buttonData.tasks.size() > 0) {
+                    paint.setColor(Color.BLACK);
+                    canvas.drawCircle(60, 30, 30, paint);
+                    paint.setColor(Color.WHITE);
+                    paint.setTextSize(50);
+                    paint.setTypeface(Typeface.create("sans-serif", Typeface.BOLD));
+                    canvas.drawText(Integer.toString(buttonData.tasks.size()), 50, 50, paint);
+                }
+                badgedIcon = new BitmapDrawable(null, bitmap);
+            }
+
+            return  badgedIcon;
         } catch (RemoteException e) {
             Slog.w(TAG, "Icon not found for " + appInfo, e);
             return null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index d0a7f8a..030501b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -248,10 +248,10 @@
             return STATE_FINGERPRINT_ERROR;
         } else if (mUnlockMethodCache.canSkipBouncer()) {
             return STATE_LOCK_OPEN;
-        } else if (fingerprintRunning && unlockingAllowed) {
-            return STATE_FINGERPRINT;
         } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
             return STATE_FACE_UNLOCK;
+        } else if (fingerprintRunning && unlockingAllowed) {
+            return STATE_FINGERPRINT;
         } else {
             return STATE_LOCKED;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
index 5c01f01..1c9b04f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
@@ -19,7 +19,11 @@
 import android.animation.LayoutTransition;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
+import android.app.IActivityManager;
+import android.app.ITaskStackListener;
 import android.content.BroadcastReceiver;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -29,8 +33,10 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.AttributeSet;
@@ -51,12 +57,12 @@
 
 /**
  * Container for application icons that appear in the navigation bar. Their appearance is similar
- * to the launcher hotseat. Clicking an icon launches the associated activity. A long click will
- * trigger a drag to allow the icons to be reordered. As an icon is dragged the other icons shift
- * to make space for it to be dropped. These layout changes are animated.
+ * to the launcher hotseat. Clicking an icon launches or activates the associated activity. A long
+ * click will trigger a drag to allow the icons to be reordered. As an icon is dragged the other
+ * icons shift to make space for it to be dropped. These layout changes are animated.
  */
 class NavigationBarApps extends LinearLayout {
-    private final static boolean DEBUG = false;
+    public final static boolean DEBUG = false;
     private final static String TAG = "NavigationBarApps";
 
     /**
@@ -97,16 +103,9 @@
         }
     };
 
-    public static NavigationBarAppsModel getModel(Context context) {
-        if (sAppsModel == null) {
-            sAppsModel = new NavigationBarAppsModel(context);
-        }
-        return sAppsModel;
-    }
-
     public NavigationBarApps(Context context, AttributeSet attrs) {
         super(context, attrs);
-        getModel(context);
+        sAppsModel = new NavigationBarAppsModel(context);
         mPackageManager = context.getPackageManager();
         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
         mLayoutInflater = LayoutInflater.from(context);
@@ -124,19 +123,27 @@
         transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
         transition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 0);
         setLayoutTransition(transition);
+
+        TaskStackListener taskStackListener = new TaskStackListener();
+        IActivityManager iam = ActivityManagerNative.getDefault();
+        try {
+            iam.registerTaskStackListener(taskStackListener);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "registerTaskStackListener failed", e);
+        }
     }
 
     // Monitor that catches events like "app uninstalled".
     private class AppPackageMonitor extends PackageMonitor {
         @Override
         public void onPackageRemoved(String packageName, int uid) {
-            postRemoveIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
+            postUnpinIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
             super.onPackageRemoved(packageName, uid);
         }
 
         @Override
         public void onPackageModified(String packageName) {
-            postRemoveIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
+            postUnpinIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
             super.onPackageModified(packageName);
         }
 
@@ -146,7 +153,7 @@
                 UserHandle user = new UserHandle(getChangingUserId());
 
                 for (String packageName : packages) {
-                    postRemoveIfUnlauncheable(packageName, user);
+                    postUnpinIfUnlauncheable(packageName, user);
                 }
             }
             super.onPackagesAvailable(packages);
@@ -158,31 +165,36 @@
                 UserHandle user = new UserHandle(getChangingUserId());
 
                 for (String packageName : packages) {
-                    postRemoveIfUnlauncheable(packageName, user);
+                    postUnpinIfUnlauncheable(packageName, user);
                 }
             }
             super.onPackagesUnavailable(packages);
         }
     }
 
-    private void postRemoveIfUnlauncheable(final String packageName, final UserHandle user) {
+    private void postUnpinIfUnlauncheable(final String packageName, final UserHandle user) {
         // This method doesn't necessarily get called in the main thread. Redirect the call into
         // the main thread.
         post(new Runnable() {
             @Override
             public void run() {
                 if (!isAttachedToWindow()) return;
-                removeIfUnlauncheable(packageName, user);
+                unpinIfUnlauncheable(packageName, user);
             }
         });
     }
 
-    private void removeIfUnlauncheable(String packageName, UserHandle user) {
-        // Remove icons for all apps that match a package that perhaps became unlauncheable.
+    private void unpinIfUnlauncheable(String packageName, UserHandle user) {
+        // Unpin icons for all apps that match a package that perhaps became unlauncheable.
+        boolean appsWereUnpinned = false;
         for(int i = getChildCount() - 1; i >= 0; --i) {
             View child = getChildAt(i);
-            AppInfo appInfo = (AppInfo)child.getTag();
-            if (appInfo == null) continue;  // Skip the drag placeholder.
+            AppButtonData appButtonData = (AppButtonData)child.getTag();
+            if (appButtonData == null) continue;  // Skip the drag placeholder.
+
+            if (!appButtonData.pinned) continue;
+
+            AppInfo appInfo = appButtonData.appInfo;
             if (!appInfo.getUser().equals(user)) continue;
 
             ComponentName appComponentName = appInfo.getComponentName();
@@ -192,10 +204,15 @@
                 continue;
             }
 
-            removeViewAt(i);
+            appButtonData.pinned = false;
+            appsWereUnpinned = true;
+
+            if (appButtonData.isEmpty()) {
+                removeViewAt(i);
+            }
         }
-        if (getChildCount() != sAppsModel.getApps().size()) {
-            saveApps();
+        if (appsWereUnpinned) {
+            savePinnedApps();
         }
     }
 
@@ -215,7 +232,8 @@
         parent.setLayoutTransition(transition);
 
         sAppsModel.setCurrentUser(ActivityManager.getCurrentUser());
-        recreateAppButtons();
+        recreatePinnedAppButtons();
+        updateRecentApps();
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -232,11 +250,23 @@
         mAppPackageMonitor.unregister();
     }
 
+    private void addAppButton(AppButtonData appButtonData) {
+        ImageView button = createAppButton(appButtonData);
+        addView(button);
+
+        AppInfo app = appButtonData.appInfo;
+        CharSequence appLabel = getAppLabel(mPackageManager, app.getComponentName());
+        button.setContentDescription(appLabel);
+
+        // Load the icon asynchronously.
+        new GetActivityIconTask(mPackageManager, button).execute(appButtonData);
+    }
+
     /**
      * Creates an ImageView icon for each pinned app. Removes any existing icons. May be called
      * to synchronize the current view with the shared data mode.
      */
-    public void recreateAppButtons() {
+    private void recreatePinnedAppButtons() {
         // Remove any existing icon buttons.
         removeAllViews();
 
@@ -244,54 +274,46 @@
         int appCount = apps.size();
         for (int i = 0; i < appCount; i++) {
             AppInfo app = apps.get(i);
-            ImageView button = createAppButton(app);
-            addView(button);
-
-            CharSequence appLabel = getAppLabel(mPackageManager, app.getComponentName());
-            button.setContentDescription(appLabel);
-
-            // Load the icon asynchronously.
-            new GetActivityIconTask(mPackageManager, button).execute(app);
+            addAppButton(new AppButtonData(app, true /* pinned */));
         }
     }
 
     /**
-     * Saves apps stored in app icons into the data model.
+     * Saves pinned apps stored in app icons into the data model.
      */
-    private void saveApps() {
+    private void savePinnedApps() {
         List<AppInfo> apps = new ArrayList<AppInfo>();
         int childCount = getChildCount();
         for (int i = 0; i != childCount; ++i) {
             View child = getChildAt(i);
-            AppInfo appInfo = (AppInfo)child.getTag();
-            if (appInfo == null) continue;  // Skip the drag placeholder.
-            apps.add(appInfo);
+            AppButtonData appButtonData = (AppButtonData)child.getTag();
+            if (appButtonData == null) continue;  // Skip the drag placeholder.
+            if(!appButtonData.pinned) continue;
+            apps.add(appButtonData.appInfo);
         }
         sAppsModel.setApps(apps);
     }
 
     /**
-     * Creates a new ImageView for a launcher activity, inflated from
-     * R.layout.navigation_bar_app_item.
+     * Creates a new ImageView for an app, inflated from R.layout.navigation_bar_app_item.
      */
-    private ImageView createAppButton(AppInfo appInfo) {
+    private ImageView createAppButton(AppButtonData appButtonData) {
         ImageView button = (ImageView) mLayoutInflater.inflate(
                 R.layout.navigation_bar_app_item, this, false /* attachToRoot */);
         button.setOnClickListener(new AppClickListener());
         // TODO: Ripple effect. Use either KeyButtonRipple or the default ripple background.
         button.setOnLongClickListener(new AppLongClickListener());
         button.setOnDragListener(new AppIconDragListener());
-        button.setTag(appInfo);
+        button.setTag(appButtonData);
         return button;
     }
 
-    // Not shared with NavigationBarRecents because the data model is specific to pinned apps.
     private class AppLongClickListener implements View.OnLongClickListener {
         @Override
         public boolean onLongClick(View v) {
             mDragView = (ImageView) v;
-            AppInfo app = (AppInfo) v.getTag();
-            startAppDrag(mDragView, app);
+            AppButtonData appButtonData = (AppButtonData) v.getTag();
+            startAppDrag(mDragView, appButtonData.appInfo);
             return true;
         }
     }
@@ -443,30 +465,30 @@
             return true;
         }
 
+        boolean dragResult = true;
         AppInfo appInfo = getAppFromDragEvent(event);
         if (appInfo == null) {
             // This wasn't a valid drop. Clean up the placeholder.
             removePlaceholderDragViewIfNeeded();
-            return false;
+            dragResult = false;
+        } else if (mDragView.getTag() == null) {
+            // This is a drag that adds a new app. Convert the placeholder to a real icon.
+            updateApp(mDragView, new AppButtonData(appInfo, true /* pinned */));
         }
-
-        // If this was an existing app being dragged then end the drag.
-        if (mDragView.getTag() != null) {
-            endDrag();
-            return true;
-        }
-
-        // The drop had valid data. Convert the placeholder to a real icon.
-        updateApp(mDragView, appInfo);
         endDrag();
-        return true;
+        return dragResult;
     }
 
     /** Cleans up at the end of a drag. */
     private void endDrag() {
+        // An earlier drag event might have canceled the drag. If so, there is nothing to do.
+        if (mDragView == null) return;
+
         mDragView.setVisibility(View.VISIBLE);
         mDragView = null;
-        saveApps();
+        savePinnedApps();
+        // Add recent tasks to the info of the potentially added app.
+        updateRecentApps();
     }
 
     /** Returns an app info from a DragEvent, or null if the data wasn't valid. */
@@ -506,9 +528,9 @@
     }
 
     /** Updates the app at a given view index. */
-    private void updateApp(ImageView button, AppInfo appInfo) {
-        button.setTag(appInfo);
-        new GetActivityIconTask(mPackageManager, button).execute(appInfo);
+    private void updateApp(ImageView button, AppButtonData appButtonData) {
+        button.setTag(appButtonData);
+        new GetActivityIconTask(mPackageManager, button).execute(appButtonData);
     }
 
     /** Removes the empty placeholder view. */
@@ -518,7 +540,6 @@
             return;
         }
         removeView(mDragView);
-        endDrag();
     }
 
     /** Cleans up at the end of the drag. */
@@ -526,6 +547,7 @@
         if (DEBUG) Slog.d(TAG, "onDragEnded");
         // If the icon wasn't already dropped into the app list then remove the placeholder.
         removePlaceholderDragViewIfNeeded();
+        endDrag();
         return true;
     }
 
@@ -561,9 +583,7 @@
      * A click listener that launches an activity.
      */
     private class AppClickListener implements View.OnClickListener {
-        @Override
-        public void onClick(View v) {
-            AppInfo appInfo = (AppInfo)v.getTag();
+        private void launchApp(AppInfo appInfo, View anchor) {
             Intent launchIntent = sAppsModel.buildAppLaunchIntent(appInfo);
             if (launchIntent == null) {
                 Toast.makeText(
@@ -576,32 +596,226 @@
             // already open in a visible window. In that case we should move the task to front
             // with minimal animation, perhaps using ActivityManager.moveTaskToFront().
             Rect sourceBounds = new Rect();
-            v.getBoundsOnScreen(sourceBounds);
+            anchor.getBoundsOnScreen(sourceBounds);
             ActivityOptions opts =
-                    ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight());
+                    ActivityOptions.makeScaleUpAnimation(
+                            anchor, 0, 0, anchor.getWidth(), anchor.getHeight());
             Bundle optsBundle = opts.toBundle();
             launchIntent.setSourceBounds(sourceBounds);
 
             mContext.startActivityAsUser(launchIntent, optsBundle, appInfo.getUser());
         }
+
+        private void activateLatestTask(List<RecentTaskInfo> tasks) {
+            // 'tasks' is guaranteed to be non-empty.
+            int latestTaskPersistentId = tasks.get(0).persistentId;
+            // Launch or bring the activity to front.
+            IActivityManager manager = ActivityManagerNative.getDefault();
+            try {
+                manager.startActivityFromRecents(latestTaskPersistentId, null /* options */);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception when activating a recent task", e);
+            } catch (IllegalArgumentException e) {
+                Slog.e(TAG, "Exception when activating a recent task", e);
+            }
+        }
+
+        @Override
+        public void onClick(View v) {
+            AppButtonData appButtonData = (AppButtonData)v.getTag();
+
+            if (appButtonData.tasks == null || appButtonData.tasks.size() == 0) {
+                launchApp(appButtonData.appInfo, v);
+            } else {
+                activateLatestTask(appButtonData.tasks);
+            }
+        }
     }
 
     private void onUserSwitched(int currentUserId) {
         sAppsModel.setCurrentUser(currentUserId);
-        recreateAppButtons();
+        recreatePinnedAppButtons();
     }
 
     private void onManagedProfileRemoved(UserHandle removedProfile) {
+        // Unpin apps from the removed profile.
+        boolean itemsWereUnpinned = false;
         for(int i = getChildCount() - 1; i >= 0; --i) {
             View view = getChildAt(i);
-            AppInfo appInfo = (AppInfo)view.getTag();
-            if (appInfo == null) return;  // Skip the drag placeholder.
-            if (!appInfo.getUser().equals(removedProfile)) continue;
+            AppButtonData appButtonData = (AppButtonData)view.getTag();
+            if (appButtonData == null) return;  // Skip the drag placeholder.
+            if (!appButtonData.pinned) continue;
+            if (!appButtonData.appInfo.getUser().equals(removedProfile)) continue;
 
-            removeViewAt(i);
+            appButtonData.pinned = false;
+            itemsWereUnpinned = true;
+            if (appButtonData.isEmpty()) {
+                removeViewAt(i);
+            }
         }
-        if (getChildCount() != sAppsModel.getApps().size()) {
-            saveApps();
+        if (itemsWereUnpinned) {
+            savePinnedApps();
+        }
+    }
+
+    /**
+     * Returns app data for a button that matches the provided app info, if it exists, or null
+     * otherwise.
+     */
+    private AppButtonData findAppButtonData(AppInfo appInfo) {
+        int size = getChildCount();
+        for (int i = 0; i < size; ++i) {
+            View view = getChildAt(i);
+            AppButtonData appButtonData = (AppButtonData)view.getTag();
+            if (appButtonData == null) continue;  // Skip the drag placeholder.
+            if (appButtonData.appInfo.equals(appInfo)) {
+                return appButtonData;
+            }
+        }
+        return null;
+    }
+
+    private void updateTasks(List<RecentTaskInfo> tasks) {
+        // Remove tasks from all app buttons.
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            View view = getChildAt(i);
+            AppButtonData appButtonData = (AppButtonData)view.getTag();
+            if (appButtonData == null) return;  // Skip the drag placeholder.
+            appButtonData.clearTasks();
+        }
+
+        // Re-add tasks to app buttons, adding new buttons if needed.
+        int size = tasks.size();
+        for (int i = 0; i != size; ++i) {
+            RecentTaskInfo task = tasks.get(i);
+            AppInfo taskAppInfo = taskToAppInfo(task);
+            if (taskAppInfo == null) continue;
+            AppButtonData appButtonData = findAppButtonData(taskAppInfo);
+            if (appButtonData == null) {
+                appButtonData = new AppButtonData(taskAppInfo, false);
+                addAppButton(appButtonData);
+            }
+            appButtonData.addTask(task);
+        }
+
+        // Remove unpinned apps that now have no tasks.
+        for (int i = getChildCount() - 1; i >= 0; --i) {
+            View view = getChildAt(i);
+            AppButtonData appButtonData = (AppButtonData)view.getTag();
+            if (appButtonData == null) return;  // Skip the drag placeholder.
+            if (appButtonData.isEmpty()) {
+                removeViewAt(i);
+            }
+        }
+
+        if (DEBUG) {
+            for (int i = getChildCount() - 1; i >= 0; --i) {
+                View view = getChildAt(i);
+                AppButtonData appButtonData = (AppButtonData)view.getTag();
+                if (appButtonData == null) return;  // Skip the drag placeholder.
+                new GetActivityIconTask(mPackageManager, (ImageView )view).execute(appButtonData);
+
+            }
+        }
+    }
+
+    private void updateRecentApps() {
+        ActivityManager activityManager =
+                (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        // TODO: Should this be getRunningTasks?
+        List<RecentTaskInfo> recentTasks = activityManager.getRecentTasksForUser(
+                ActivityManager.getMaxAppRecentsLimitStatic(),
+                ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
+                        ActivityManager.RECENT_IGNORE_UNAVAILABLE |
+                        ActivityManager.RECENT_INCLUDE_PROFILES,
+                UserHandle.USER_CURRENT);
+        if (DEBUG) Slog.d(TAG, "Got recents " + recentTasks.size());
+        updateTasks(recentTasks);
+    }
+
+    private static ComponentName getActivityForTask(RecentTaskInfo task) {
+        // If the task was started from an alias, return the actual activity component that was
+        // initially started.
+        if (task.origActivity != null) {
+            return task.origActivity;
+        }
+        // Prefer the first activity of the task.
+        if (task.baseActivity != null) {
+            return task.baseActivity;
+        }
+        // Then goes the activity that started the task.
+        if (task.realActivity != null) {
+            return task.realActivity;
+        }
+        // This should not happen, but fall back to the base intent's activity component name.
+        return task.baseIntent.getComponent();
+    }
+
+    private ComponentName getLaunchComponentForPackage(String packageName, int userId) {
+        // This code is based on ApplicationPackageManager.getLaunchIntentForPackage.
+        PackageManager packageManager = mContext.getPackageManager();
+
+        // First see if the package has an INFO activity; the existence of
+        // such an activity is implied to be the desired front-door for the
+        // overall package (such as if it has multiple launcher entries).
+        Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
+        intentToResolve.addCategory(Intent.CATEGORY_INFO);
+        intentToResolve.setPackage(packageName);
+        List<ResolveInfo> ris = packageManager.queryIntentActivitiesAsUser(
+                intentToResolve, 0, userId);
+
+        // Otherwise, try to find a main launcher activity.
+        if (ris == null || ris.size() <= 0) {
+            // reuse the intent instance
+            intentToResolve.removeCategory(Intent.CATEGORY_INFO);
+            intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
+            intentToResolve.setPackage(packageName);
+            ris = packageManager.queryIntentActivitiesAsUser(intentToResolve, 0, userId);
+        }
+        if (ris == null || ris.size() <= 0) {
+            Slog.e(TAG, "Failed to build intent for " + packageName);
+            return null;
+        }
+        return new ComponentName(ris.get(0).activityInfo.packageName,
+                ris.get(0).activityInfo.name);
+    }
+
+    private AppInfo taskToAppInfo(RecentTaskInfo task) {
+        ComponentName componentName = getActivityForTask(task);
+        UserHandle taskUser = new UserHandle(task.userId);
+        AppInfo appInfo = new AppInfo(componentName, taskUser);
+
+        if (sAppsModel.buildAppLaunchIntent(appInfo) == null) {
+            // If task's activity is not launcheable, fall back to a launch component of the
+            // task's package.
+            ComponentName component = getLaunchComponentForPackage(
+                    componentName.getPackageName(), task.userId);
+
+            if (component == null) {
+                return null;
+            }
+
+            appInfo = new AppInfo(component, taskUser);
+        }
+
+        return appInfo;
+    }
+
+    /**
+     * A listener that updates the app buttons whenever the recents task stack changes.
+     */
+    private class TaskStackListener extends ITaskStackListener.Stub {
+        @Override
+        public void onTaskStackChanged() throws RemoteException {
+            // Post the message back to the UI thread.
+            post(new Runnable() {
+                @Override
+                public void run() {
+                    if (isAttachedToWindow()) {
+                        updateRecentApps();
+                    }
+                }
+            });
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java
deleted file mode 100644
index 7ff56ba..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * 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.systemui.statusbar.phone;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RecentTaskInfo;
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.ITaskStackListener;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.util.SparseBooleanArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.systemui.R;
-
-import java.util.List;
-
-/**
- * Recent task icons appearing in the navigation bar. Touching an icon brings the activity to the
- * front. The tag for each icon's View contains the RecentTaskInfo.
- */
-class NavigationBarRecents extends LinearLayout {
-    private final static boolean DEBUG = false;
-    private final static String TAG = "NavigationBarRecents";
-
-    // Maximum number of icons to show.
-    // TODO: Implement an overflow UI so the shelf can display an unlimited number of recents.
-    private final static int MAX_RECENTS = 10;
-
-    private final ActivityManager mActivityManager;
-    private final PackageManager mPackageManager;
-    private final LayoutInflater mLayoutInflater;
-    // All icons share the same long-click listener.
-    private final AppLongClickListener mAppLongClickListener;
-    private final TaskStackListenerImpl mTaskStackListener;
-
-    public NavigationBarRecents(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        mPackageManager = getContext().getPackageManager();
-        mLayoutInflater = LayoutInflater.from(context);
-        mAppLongClickListener = new AppLongClickListener(context);
-
-        // Listen for task stack changes and refresh when they happen. Update notifications happen
-        // on an IPC thread, so use Handler to handle the message on the main thread.
-        // TODO: This has too much latency. It only adds the icon when app launch is completed
-        // and the launch animation is done playing. This class should add the icon immediately
-        // when the launch starts.
-        Handler handler = new Handler();
-        mTaskStackListener = new TaskStackListenerImpl(handler);
-        IActivityManager iam = ActivityManagerNative.getDefault();
-        try {
-            iam.registerTaskStackListener(mTaskStackListener);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void updateRecentApps() {
-        // TODO: Should this be getRunningTasks?
-        // TODO: Query other UserHandles?
-        List<RecentTaskInfo> recentTasks = mActivityManager.getRecentTasksForUser(
-                MAX_RECENTS,
-                ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
-                ActivityManager.RECENT_IGNORE_UNAVAILABLE |
-                ActivityManager.RECENT_INCLUDE_PROFILES,
-                UserHandle.USER_CURRENT);
-        if (DEBUG) Slog.d(TAG, "Got recents " + recentTasks.size());
-        removeMissingRecents(recentTasks);
-        addNewRecents(recentTasks);
-    }
-
-    // Removes any icons that disappeared from recents.
-    private void removeMissingRecents(List<RecentTaskInfo> recentTasks) {
-        // Build a set of the new task ids.
-        SparseBooleanArray newTaskIds = new SparseBooleanArray();
-        for (RecentTaskInfo task : recentTasks) {
-            newTaskIds.put(task.persistentId, true);
-        }
-
-        // Iterate through the currently displayed tasks. If they no longer exist in recents,
-        // remove them.
-        int i = 0;
-        while (i < getChildCount()) {
-            RecentTaskInfo currentTask = (RecentTaskInfo) getChildAt(i).getTag();
-            if (!newTaskIds.get(currentTask.persistentId)) {
-                if (DEBUG) Slog.d(TAG, "Removing " + currentTask.baseIntent);
-                removeViewAt(i);
-            } else {
-                i++;
-            }
-        }
-    }
-
-    // Adds new tasks at the end of the icon list.
-    private void addNewRecents(List<RecentTaskInfo> recentTasks) {
-        // Build a set of the current task ids.
-        SparseBooleanArray currentTaskIds = new SparseBooleanArray();
-        for (int i = 0; i < getChildCount(); i++) {
-            RecentTaskInfo task = (RecentTaskInfo) getChildAt(i).getTag();
-            currentTaskIds.put(task.persistentId, true);
-        }
-
-        // Add tasks that don't currently exist to the end of the view.
-        for (RecentTaskInfo task : recentTasks) {
-            // Don't overflow the list.
-            if (getChildCount() >= MAX_RECENTS) {
-                return;
-            }
-            // Don't add tasks that are already being shown.
-            if (currentTaskIds.get(task.persistentId)) {
-                continue;
-            }
-            addRecentAppButton(task);
-        }
-    }
-
-    // Adds an icon at the end of the shelf.
-    private void addRecentAppButton(RecentTaskInfo task) {
-        if (DEBUG) Slog.d(TAG, "Adding " + task.baseIntent);
-
-        // Add an icon for the task.
-        ImageView button = (ImageView) mLayoutInflater.inflate(
-                R.layout.navigation_bar_app_item, this, false /* attachToRoot */);
-        button.setOnLongClickListener(mAppLongClickListener);
-        addView(button);
-
-        ComponentName activityName = getActivityForTask(task);
-        CharSequence appLabel = NavigationBarApps.getAppLabel(mPackageManager, activityName);
-        button.setContentDescription(appLabel);
-
-        // Use the View's tag to store metadata for drag and drop.
-        button.setTag(task);
-
-        button.setVisibility(View.VISIBLE);
-        // Load the activity icon on a background thread.
-        AppInfo app = new AppInfo(activityName, new UserHandle(task.userId));
-        new GetActivityIconTask(mPackageManager, button).execute(app);
-
-        final int taskPersistentId = task.persistentId;
-        button.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                // Launch or bring the activity to front.
-                IActivityManager manager = ActivityManagerNative.getDefault();
-                try {
-                    manager.startActivityFromRecents(taskPersistentId, null /* options */);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Exception when activating a recent task", e);
-                } catch (IllegalArgumentException e) {
-                    Slog.e(TAG, "Exception when activating a recent task", e);
-                }
-            }
-        });
-    }
-
-    private static ComponentName getActivityForTask(RecentTaskInfo task) {
-        // If the task was started from an alias, return the actual activity component that was
-        // initially started.
-        if (task.origActivity != null) {
-            return task.origActivity;
-        }
-        // Prefer the first activity of the task.
-        if (task.baseActivity != null) {
-            return task.baseActivity;
-        }
-        // Then goes the activity that started the task.
-        if (task.realActivity != null) {
-            return task.realActivity;
-        }
-        // This should not happen, but fall back to the base intent's activity component name.
-        return task.baseIntent.getComponent();
-    }
-
-    /**
-     * A listener that updates the app buttons whenever the recents task stack changes.
-     * NOTE: This is not the right way to do this.
-     */
-    private class TaskStackListenerImpl extends ITaskStackListener.Stub {
-        // Handler to post messages to the UI thread.
-        private Handler mHandler;
-
-        public TaskStackListenerImpl(Handler handler) {
-            mHandler = handler;
-        }
-
-        @Override
-        public void onTaskStackChanged() throws RemoteException {
-            // Post the message back to the UI thread.
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    updateRecentApps();
-                }
-            });
-        }
-    }
-
-    /** Starts a drag on long-click on an app icon. */
-    private static class AppLongClickListener implements View.OnLongClickListener {
-        private final Context mContext;
-
-        public AppLongClickListener(Context context) {
-            mContext = context;
-        }
-
-        private ComponentName getLaunchComponentForPackage(String packageName, int userId) {
-            // This code is based on ApplicationPackageManager.getLaunchIntentForPackage.
-            PackageManager packageManager = mContext.getPackageManager();
-
-            // First see if the package has an INFO activity; the existence of
-            // such an activity is implied to be the desired front-door for the
-            // overall package (such as if it has multiple launcher entries).
-            Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
-            intentToResolve.addCategory(Intent.CATEGORY_INFO);
-            intentToResolve.setPackage(packageName);
-            List<ResolveInfo> ris = packageManager.queryIntentActivitiesAsUser(
-                    intentToResolve, 0, userId);
-
-            // Otherwise, try to find a main launcher activity.
-            if (ris == null || ris.size() <= 0) {
-                // reuse the intent instance
-                intentToResolve.removeCategory(Intent.CATEGORY_INFO);
-                intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
-                intentToResolve.setPackage(packageName);
-                ris = packageManager.queryIntentActivitiesAsUser(intentToResolve, 0, userId);
-            }
-            if (ris == null || ris.size() <= 0) {
-                Slog.e(TAG, "Failed to build intent for " + packageName);
-                return null;
-            }
-            return new ComponentName(ris.get(0).activityInfo.packageName,
-                    ris.get(0).activityInfo.name);
-        }
-
-        @Override
-        public boolean onLongClick(View v) {
-            ImageView icon = (ImageView) v;
-
-            // The drag will go to the pinned section, which wants to launch the main activity
-            // for the task's package.
-            RecentTaskInfo task = (RecentTaskInfo) v.getTag();
-            ComponentName componentName = getActivityForTask(task);
-            UserHandle taskUser = new UserHandle(task.userId);
-            AppInfo appInfo = new AppInfo(componentName, taskUser);
-
-            if (NavigationBarApps.getModel(mContext).buildAppLaunchIntent(appInfo) == null) {
-                // If task's activity is not launcheable, fall back to a launch component of the
-                // task's package.
-                ComponentName component = getLaunchComponentForPackage(
-                        componentName.getPackageName(), task.userId);
-
-                if (component == null) {
-                    return false;
-                }
-
-                appInfo = new AppInfo(component, taskUser);
-            }
-
-            if (DEBUG) {
-                Slog.d(TAG, "Start drag with " + appInfo.getComponentName().flattenToString());
-            }
-
-            NavigationBarApps.startAppDrag(icon, appInfo);
-            return true;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 7de7a7b..f37383a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -492,14 +492,6 @@
         }
 
         updateTaskSwitchHelper();
-
-        // If using the app shelf, synchronize the current icons to the data model.
-        NavigationBarApps apps =
-                (NavigationBarApps) mCurrentView.findViewById(R.id.navigation_bar_apps);
-        if (apps != null) {
-            apps.recreateAppButtons();
-        }
-
         setNavigationIconHints(mNavigationIconHints, true);
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 57769e7..7051b52 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -205,9 +205,7 @@
 
     private final UserManager mUserManager;
 
-    private final LockPatternUtils mLockPatternUtils;
-
-    private int mCurrentUserId = UserHandle.USER_OWNER;
+    private int mCurrentUserId = UserHandle.USER_SYSTEM;
 
     //TODO: Remove this hack
     private boolean mInitialized;
@@ -230,7 +228,6 @@
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mSecurityPolicy = new SecurityPolicy();
         mMainHandler = new MainHandler(mContext.getMainLooper());
-        mLockPatternUtils = new LockPatternUtils(context);
         registerBroadcastReceivers();
         new AccessibilityContentObserver(mMainHandler).register(
                 context.getContentResolver());
@@ -866,17 +863,18 @@
     }
 
     // Called only during settings restore; currently supports only the owner user
+    // TODO: http://b/22388012
     void restoreEnabledAccessibilityServicesLocked(String oldSetting, String newSetting) {
         readComponentNamesFromStringLocked(oldSetting, mTempComponentNameSet, false);
         readComponentNamesFromStringLocked(newSetting, mTempComponentNameSet, true);
 
-        UserState userState = getUserStateLocked(UserHandle.USER_OWNER);
+        UserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
         userState.mEnabledServices.clear();
         userState.mEnabledServices.addAll(mTempComponentNameSet);
         persistComponentNamesToSettingLocked(
                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                 userState.mEnabledServices,
-                UserHandle.USER_OWNER);
+                UserHandle.USER_SYSTEM);
         onUserStateChangedLocked(userState);
     }
 
@@ -1646,10 +1644,6 @@
         DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId);
     }
 
-    private boolean hasRunningServicesLocked(UserState userState) {
-        return !userState.mBoundServices.isEmpty() || !userState.mBindingServices.isEmpty();
-    }
-
     private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
         IBinder windowToken = mGlobalWindowTokens.get(windowId);
         if (windowToken == null) {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 50bd544..d5c4a41 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -273,7 +273,8 @@
             sysUiUid = mContext.getPackageManager().getPackageUid("com.android.systemui",
                     UserHandle.USER_OWNER);
         } catch (PackageManager.NameNotFoundException e) {
-            Log.wtf(TAG, "Unable to resolve SystemUI's UID.", e);
+            // Some platforms, such as wearables do not have a system ui.
+            Log.w(TAG, "Unable to resolve SystemUI's UID.", e);
         }
         mSystemUiUid = sysUiUid;
     }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2bcee91..1f4427f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -511,7 +511,6 @@
 
             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
             if (list.contains(nai)) {
-                loge("Attempting to register duplicate agent for type " + type + ": " + nai);
                 return;
             }
 
@@ -4280,7 +4279,7 @@
         boolean keep = newNetwork.isVPN();
         boolean isNewDefault = false;
         NetworkAgentInfo oldDefaultNetwork = null;
-        if (DBG) log("rematching " + newNetwork.name());
+        if (VDBG) log("rematching " + newNetwork.name());
         // Find and migrate to this Network any NetworkRequests for
         // which this network is now the best.
         ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
@@ -4317,6 +4316,7 @@
                 }
                 if (currentNetwork == null ||
                         currentNetwork.getCurrentScore() < newNetwork.getCurrentScore()) {
+                    if (DBG) log("rematch for " + newNetwork.name());
                     if (currentNetwork != null) {
                         if (DBG) log("   accepting network in place of " + currentNetwork.name());
                         currentNetwork.networkRequests.remove(nri.request.requestId);
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 94316fe..e8b90d8 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -25,6 +25,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.util.Slog;
 
@@ -84,7 +85,7 @@
         mContext = context;
         mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
         mBlockDeviceSize = -1; // Load lazily
-        mAllowedUid = getAllowedUid(UserHandle.USER_OWNER);
+        mAllowedUid = getAllowedUid(UserHandle.USER_SYSTEM);
     }
 
     private int getAllowedUid(int userHandle) {
@@ -131,9 +132,12 @@
         }
     }
 
-    private void enforceIsOwner() {
-        if (!Binder.getCallingUserHandle().isOwner()) {
-            throw new SecurityException("Only the Owner is allowed to change OEM unlock state");
+    private void enforceIsAdmin() {
+        final int userId = UserHandle.getCallingUserId();
+        final boolean isAdmin = UserManager.get(mContext).isUserAdmin(userId);
+        if (!isAdmin) {
+            throw new SecurityException(
+                    "Only the Admin user is allowed to change OEM unlock state");
         }
     }
     private int getTotalDataSizeLocked(DataInputStream inputStream) throws IOException {
@@ -434,7 +438,7 @@
                 return;
             }
             enforceOemUnlockPermission();
-            enforceIsOwner();
+            enforceIsAdmin();
 
             synchronized (mLock) {
                 doSetOemUnlockEnabledLocked(enabled);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0119000..4949138 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2085,7 +2085,8 @@
     }
 
     private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses,
-            boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services) {
+            boolean evenPersistent, boolean doit, boolean killProcess,
+            ArrayMap<ComponentName, ServiceRecord> services) {
         boolean didSomething = false;
         for (int i = services.size() - 1; i >= 0; i--) {
             ServiceRecord service = services.valueAt(i);
@@ -2101,7 +2102,7 @@
                 didSomething = true;
                 Slog.i(TAG, "  Force stopping service " + service);
                 if (service.app != null) {
-                    service.app.removed = true;
+                    service.app.removed = killProcess;
                     if (!service.app.persistent) {
                         service.app.services.remove(service);
                     }
@@ -2118,7 +2119,7 @@
     }
 
     boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses,
-            int userId, boolean evenPersistent, boolean doit) {
+            int userId, boolean evenPersistent, boolean killProcess, boolean doit) {
         boolean didSomething = false;
 
         if (mTmpCollectionResults != null) {
@@ -2128,7 +2129,7 @@
         if (userId == UserHandle.USER_ALL) {
             for (int i = mServiceMap.size() - 1; i >= 0; i--) {
                 didSomething |= collectPackageServicesLocked(packageName, filterByClasses,
-                        evenPersistent, doit, mServiceMap.valueAt(i).mServicesByName);
+                        evenPersistent, doit, killProcess, mServiceMap.valueAt(i).mServicesByName);
                 if (!doit && didSomething) {
                     return true;
                 }
@@ -2138,7 +2139,7 @@
             if (smap != null) {
                 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
                 didSomething = collectPackageServicesLocked(packageName, filterByClasses,
-                        evenPersistent, doit, items);
+                        evenPersistent, doit, killProcess, items);
             }
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3554c39..81936ee 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4225,7 +4225,7 @@
                 throw new IllegalArgumentException("Task " + taskId + " not found.");
             }
             if (task.getRootActivity() != null) {
-                moveTaskToFrontLocked(task.taskId, 0, null);
+                moveTaskToFrontLocked(task.taskId, 0, options);
                 return ActivityManager.START_TASK_TO_FRONT;
             }
             callingUid = task.mCallingUid;
@@ -5647,7 +5647,7 @@
     }
 
     private void cleanupDisabledPackageComponentsLocked(
-            String packageName, int userId, String[] changedClasses) {
+            String packageName, int userId, boolean killProcess, String[] changedClasses) {
 
         Set<String> disabledClasses = null;
         boolean packageDisabled = false;
@@ -5717,7 +5717,7 @@
 
         // Clean-up disabled services.
         mServices.bringDownDisabledPackageServicesLocked(
-                packageName, disabledClasses, userId, false, true);
+                packageName, disabledClasses, userId, false, killProcess, true);
 
         // Clean-up disabled providers.
         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
@@ -5802,7 +5802,7 @@
         }
 
         if (mServices.bringDownDisabledPackageServicesLocked(
-                packageName, null, userId, evenPersistent, doit)) {
+                packageName, null, userId, evenPersistent, true, doit)) {
             if (!doit) {
                 return true;
             }
@@ -16892,7 +16892,9 @@
                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
                                 boolean fullUninstall = removed &&
                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
-                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
+                                final boolean killProcess =
+                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
+                                if (killProcess) {
                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                             false, true, true, false, fullUninstall, userId,
@@ -16912,7 +16914,7 @@
                                         mBatteryStatsService.notePackageUninstalled(ssp);
                                     }
                                 } else {
-                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
+                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
                                             intent.getStringArrayExtra(
                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
                                 }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 37ddd4d..751acb6 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -18,7 +18,6 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_ID;
 import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.HOME_STACK_ID;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
 
@@ -391,7 +390,9 @@
 
     void setBounds(Rect bounds) {
         mBounds = mFullscreen ? null : new Rect(bounds);
-        mTaskPositioner.configure(bounds);
+        if (mTaskPositioner != null) {
+            mTaskPositioner.configure(bounds);
+        }
     }
 
     boolean okToShowLocked(ActivityRecord r) {
@@ -4548,10 +4549,11 @@
             boolean toTop) {
         TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
                 voiceInteractor);
+        // add the task to stack first, mTaskPositioner might need the stack association
+        addTask(task, toTop, false);
         if (mTaskPositioner != null) {
             mTaskPositioner.updateDefaultBounds(task, mTaskHistory, info.initialLayout);
         }
-        addTask(task, toTop, false);
         return task;
     }
 
@@ -4588,19 +4590,20 @@
 
     void addConfigOverride(ActivityRecord r, TaskRecord task) {
         final Rect bounds = task.getLaunchBounds();
-        final Configuration config = task.updateOverrideConfiguration(mStackId, bounds);
+        task.updateOverrideConfiguration(bounds);
         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                 (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                 r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind,
-                bounds, config);
+                bounds, task.mOverrideConfig);
         r.taskConfigOverride = task.mOverrideConfig;
     }
 
     private void setAppTask(ActivityRecord r, TaskRecord task) {
         final Rect bounds = task.getLaunchBounds();
-        final Configuration config = task.updateOverrideConfiguration(mStackId, bounds);
-        mWindowManager.setAppTask(r.appToken, task.taskId, task.getLaunchBounds(), config);
+        task.updateOverrideConfiguration(bounds);
+        mWindowManager.setAppTask(
+                r.appToken, task.taskId, task.getLaunchBounds(), task.mOverrideConfig);
         r.taskConfigOverride = task.mOverrideConfig;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 33e0ef8..b7c55d4 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1764,7 +1764,7 @@
         return ACTIVITY_RESTRICTION_NONE;
     }
 
-    ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
+    ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds) {
         final TaskRecord task = r.task;
 
         // On leanback only devices we should keep all activities in the same stack.
@@ -1815,10 +1815,10 @@
             }
 
             // If there is no suitable dynamic stack then we figure out which static stack to use.
-            stack = getStack(
-                    task != null
-                            ? task.getLaunchStackId(mFocusedStack) : FULLSCREEN_WORKSPACE_STACK_ID,
-                    CREATE_IF_NEEDED, ON_TOP);
+            int stackId = task != null ? task.getLaunchStackId() :
+                        bounds != null ? FREEFORM_WORKSPACE_STACK_ID :
+                                         FULLSCREEN_WORKSPACE_STACK_ID;
+            stack = getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
                     + r + " stackId=" + stack.mStackId);
             return stack;
@@ -1846,6 +1846,22 @@
         final Intent intent = r.intent;
         final int callingUid = r.launchedFromUid;
 
+        boolean overrideBounds = false;
+        Rect newBounds = null;
+        if (r.info.resizeable || (inTask != null && inTask.mResizeable)) {
+            if (intent.hasExtra(ActivityOptions.KEY_BOUNDS)) {
+                overrideBounds = true;
+                newBounds = Rect.unflattenFromString(
+                        intent.getStringExtra(ActivityOptions.KEY_BOUNDS));
+            } else if (options != null) {
+                ActivityOptions opts = new ActivityOptions(options);
+                if (opts.hasBounds()) {
+                    overrideBounds = true;
+                    newBounds = opts.getBounds();
+                }
+            }
+        }
+
         // In some flows in to this function, we retrieve the task record and hold on to it
         // without a lock before calling back in to here...  so the task at this point may
         // not actually be in recents.  Check for that, and if it isn't in recents just
@@ -2199,7 +2215,8 @@
                             if (task != null && task.stack == null) {
                                 // Target stack got cleared when we all activities were removed
                                 // above. Go ahead and reset it.
-                                targetStack = computeStackFocus(sourceRecord, false /* newTask */);
+                                targetStack = computeStackFocus(
+                                        sourceRecord, false /* newTask */, null /* bounds */);
                                 targetStack.addTask(
                                         task, !launchTaskBehind /* toTop */, false /* moving */);
                             }
@@ -2325,7 +2342,7 @@
         if (r.resultTo == null && inTask == null && !addingToTask
                 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
             newTask = true;
-            targetStack = computeStackFocus(r, newTask);
+            targetStack = computeStackFocus(r, newTask, newBounds);
             if (doResume) {
                 targetStack.moveToFront("startingNewTask");
             }
@@ -2336,6 +2353,9 @@
                         newTaskIntent != null ? newTaskIntent : intent,
                         voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
                         taskToAffiliate);
+                if (overrideBounds) {
+                    r.task.updateOverrideConfiguration(newBounds);
+                }
                 if (DEBUG_TASKS) Slog.v(TAG_TASKS,
                         "Starting new activity " + r + " in new task " + r.task);
             } else {
@@ -2420,6 +2440,14 @@
                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
             }
+            if (overrideBounds) {
+                inTask.updateOverrideConfiguration(newBounds);
+                int stackId = inTask.getLaunchStackId();
+                if (stackId != inTask.stack.mStackId) {
+                    moveTaskToStackUncheckedLocked(
+                            inTask, stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront");
+                }
+            }
             targetStack = inTask.stack;
             targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
                     "inTaskToFront");
@@ -2457,7 +2485,7 @@
             // This not being started from an existing activity, and not part
             // of a new task...  just put it in the top task, though these days
             // this case should never happen.
-            targetStack = computeStackFocus(r, newTask);
+            targetStack = computeStackFocus(r, newTask, null /* bounds */);
             if (doResume) {
                 targetStack.moveToFront("addingToTopTask");
             }
@@ -2816,9 +2844,26 @@
                     + task + " to front. Stack is null");
             return;
         }
-        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
+
+        int stackId = task.stack.mStackId;
+        if (task.mResizeable && options != null) {
+            ActivityOptions opts = new ActivityOptions(options);
+            if (opts.hasBounds()) {
+                Rect bounds = opts.getBounds();
+                task.updateOverrideConfiguration(bounds);
+                mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig, false);
+                stackId = task.getLaunchStackId();
+            }
+        }
+
+        if (stackId != task.stack.mStackId) {
+            moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, FORCE_FOCUS, reason);
+        } else {
+            task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
                 task.getTopActivity() == null ? null : task.getTopActivity().appTimeTracker,
                 reason);
+        }
+
         if (DEBUG_STACK) Slog.d(TAG_STACK,
                 "findTaskToMoveToFront: moved to front of stack=" + task.stack);
     }
@@ -2925,7 +2970,7 @@
             ArrayList<TaskRecord> tasks = stack.getAllTasks();
             for (int i = tasks.size() - 1; i >= 0; i--) {
                 TaskRecord task = tasks.get(i);
-                task.updateOverrideConfiguration(stackId, bounds);
+                task.updateOverrideConfiguration(bounds);
                 mTmpConfigs.put(task.taskId, task.mOverrideConfig);
                 mTmpBounds.put(task.taskId, task.mBounds);
             }
@@ -3007,7 +3052,7 @@
             // Task doesn't exist in window manager yet (e.g. was restored from recents).
             // All we can do for now is update the bounds so it can be used when the task is
             // added to window manager.
-            task.mBounds = task.mLastNonFullscreenBounds = new Rect(bounds);
+            task.updateOverrideConfiguration(bounds);
             if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
                 // re-restore the task so it can have the proper stack association.
                 restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
@@ -3029,7 +3074,7 @@
             moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
         }
 
-        final Configuration overrideConfig =  task.updateOverrideConfiguration(stackId, bounds);
+        final Configuration overrideConfig =  task.updateOverrideConfiguration(bounds);
         // This variable holds information whether the configuration didn't change in a signficant
         // way and the activity was kept the way it was. If it's false, it means the activity had
         // to be relaunched due to configuration change.
@@ -3043,6 +3088,12 @@
                 ensureActivitiesVisibleLocked(r, 0);
                 if (!kept) {
                     resumeTopActivitiesLocked(stack, null, null);
+                    // We are about to relaunch the activity because its configuration changed due
+                    // to size change. The activity will first remove the old window and then add a
+                    // new one. This call will tell window manager about this, so it can preserve
+                    // the old window until the new one is drawn. This prevents having a gap between
+                    // the removal and addition, in which no window is visible.
+                    mWindowManager.setReplacingWindow(r.appToken);
                 }
             }
         }
@@ -3081,8 +3132,7 @@
      */
     private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
         if (stackId == INVALID_STACK_ID) {
-            stackId = mLeanbackOnlyDevice ?
-                    mHomeStack.mStackId : task.getLaunchStackId(mFocusedStack);
+            stackId = mLeanbackOnlyDevice ? mHomeStack.mStackId : task.getLaunchStackId();
         }
         if (task.stack != null) {
             // Task has already been restored once. See if we need to do anything more
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index 735c06f..3d45915 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
@@ -235,7 +234,7 @@
                 break;
             }
         }
-        task.updateOverrideConfiguration(FREEFORM_WORKSPACE_STACK_ID, proposal);
+        task.updateOverrideConfiguration(proposal);
     }
 
     private boolean shiftedToFar(Rect start, int shiftPolicy) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 12c7b86..5694e704 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -20,7 +20,6 @@
 import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.HOME_STACK_ID;
-import static android.app.ActivityManager.INVALID_STACK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
@@ -228,8 +227,6 @@
 
     Configuration mOverrideConfig = Configuration.EMPTY;
 
-    private Rect mTmpRect = new Rect();
-
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
             IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
         mService = service;
@@ -1174,7 +1171,7 @@
                 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
                 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
                 callingUid, callingPackage, resizeable, privileged);
-        task.updateOverrideConfiguration(INVALID_STACK_ID, bounds);
+        task.updateOverrideConfiguration(bounds);
 
         for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
             activities.get(activityNdx).task = task;
@@ -1188,12 +1185,12 @@
      * Update task's override configuration based on the bounds.
      * @return Update configuration or null if there is no change.
      */
-    Configuration updateOverrideConfiguration(int stackId, Rect bounds) {
-        if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
+    Configuration updateOverrideConfiguration(Rect bounds) {
+        if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
             // For freeform stack we don't adjust the size of the tasks to match that of the
             // stack, but we do try to make sure the tasks are still contained with the
             // bounds of the stack.
-            bounds = fitWithinBounds(bounds);
+            fitWithinBounds(bounds, stack.mBounds);
         }
         if (Objects.equals(mBounds, bounds)) {
             return null;
@@ -1231,20 +1228,16 @@
         return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
     }
 
-    /** Returns the stack that should be used to launch this task. */
-    int getLaunchStackId(ActivityStack focusStack) {
-        if (stack != null) {
-            // We are already in a stack silly...
-            return stack.mStackId;
-        }
-        if (isHomeTask()) {
+    /**
+     * Returns the correct stack to use based on task type and currently set bounds,
+     * regardless of the focused stack and current stack association of the task.
+     * The task will be moved (and stack focus changed) later if necessary.
+     */
+    int getLaunchStackId() {
+        if (!isApplicationTask()) {
             return HOME_STACK_ID;
         }
-        if (focusStack != null && focusStack.mStackId != HOME_STACK_ID) {
-            // Like it or not you are going in the focused stack!
-            return focusStack.mStackId;
-        }
-        if (mBounds != null || mLastNonFullscreenBounds != null) {
+        if (mBounds != null) {
             return FREEFORM_WORKSPACE_STACK_ID;
         }
         return FULLSCREEN_WORKSPACE_STACK_ID;
@@ -1262,39 +1255,43 @@
         return mLastNonFullscreenBounds;
     }
 
-    /** Fits the tasks within the input bounds adjusting the task bounds as needed.
-     *  @param bounds Bounds to fit the task within. Nothing is done if null.
-     *  @return Returns final configuration after updating with the adjusted bounds.
-     *  */
-    Rect fitWithinBounds(Rect bounds) {
-        if (bounds == null || mBounds == null || bounds.contains(mBounds)) {
-            return bounds;
+    /**
+     * Adjust bounds to stay within stack bounds.
+     *
+     * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
+     * that keep them unchanged, but be contained within the stack bounds.
+     *
+     * @param bounds Bounds to be adjusted.
+     * @param stackBounds Bounds within which the other bounds should remain.
+     */
+    private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
+        if (stackBounds == null || stackBounds.contains(bounds)) {
+            return;
         }
-        mTmpRect.set(mBounds);
 
-        if (mBounds.left < bounds.left || mBounds.right > bounds.right) {
-            final int maxRight = bounds.right - (bounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
-            int horizontalDiff = bounds.left - mBounds.left;
-            if ((horizontalDiff < 0 && mBounds.left >= maxRight)
-                    || (mBounds.left + horizontalDiff >= maxRight)) {
-                horizontalDiff = maxRight - mBounds.left;
+        if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
+            final int maxRight = stackBounds.right
+                    - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
+            int horizontalDiff = stackBounds.left - bounds.left;
+            if ((horizontalDiff < 0 && bounds.left >= maxRight)
+                    || (bounds.left + horizontalDiff >= maxRight)) {
+                horizontalDiff = maxRight - bounds.left;
             }
-            mTmpRect.left += horizontalDiff;
-            mTmpRect.right += horizontalDiff;
+            bounds.left += horizontalDiff;
+            bounds.right += horizontalDiff;
         }
 
-        if (mBounds.top < bounds.top || mBounds.bottom > bounds.bottom) {
-            final int maxBottom = bounds.bottom - (bounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
-            int verticalDiff = bounds.top - mBounds.top;
-            if ((verticalDiff < 0 && mBounds.top >= maxBottom)
-                    || (mBounds.top + verticalDiff >= maxBottom)) {
-                verticalDiff = maxBottom - mBounds.top;
+        if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
+            final int maxBottom = stackBounds.bottom
+                    - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
+            int verticalDiff = stackBounds.top - bounds.top;
+            if ((verticalDiff < 0 && bounds.top >= maxBottom)
+                    || (bounds.top + verticalDiff >= maxBottom)) {
+                verticalDiff = maxBottom - bounds.top;
             }
-            mTmpRect.top += verticalDiff;
-            mTmpRect.bottom += verticalDiff;
+            bounds.top += verticalDiff;
+            bounds.bottom += verticalDiff;
         }
-
-        return mTmpRect;
     }
 
     void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 67c9ee8..0023258 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -259,7 +259,7 @@
     }
 
     private boolean inLockoutMode() {
-        return mFailedAttempts > MAX_FAILED_ATTEMPTS;
+        return mFailedAttempts >= MAX_FAILED_ATTEMPTS;
     }
 
     private void resetFailedAttempts() {
@@ -275,7 +275,7 @@
 
     private boolean handleFailedAttempt(ClientMonitor clientMonitor) {
         mFailedAttempts++;
-        if (mFailedAttempts > MAX_FAILED_ATTEMPTS) {
+        if (inLockoutMode()) {
             // Failing multiple times will continue to push out the lockout time.
             mHandler.removeCallbacks(mLockoutReset);
             mHandler.postDelayed(mLockoutReset, FAIL_LOCKOUT_TIMEOUT_MS);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 17b4f9c..5a13672 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.input;
 
 import android.view.Display;
+import com.android.internal.os.SomeArgs;
 import com.android.internal.R;
 import com.android.internal.util.XmlUtils;
 import com.android.server.DisplayThread;
@@ -52,6 +53,7 @@
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.InputManager;
 import android.hardware.input.InputManagerInternal;
+import android.hardware.input.ITabletModeChangedListener;
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.TouchCalibration;
 import android.os.Binder;
@@ -93,6 +95,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 
 import libcore.io.Streams;
 import libcore.util.Objects;
@@ -112,6 +115,7 @@
     private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3;
     private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4;
     private static final int MSG_RELOAD_DEVICE_ALIASES = 5;
+    private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 6;
 
     // Pointer to native input manager service object.
     private final long mPtr;
@@ -124,6 +128,13 @@
     private boolean mSystemReady;
     private NotificationManager mNotificationManager;
 
+    private final Object mTabletModeLock = new Object();
+    // List of currently registered tablet mode changed listeners by process id
+    private final SparseArray<TabletModeChangedListenerRecord> mTabletModeChangedListeners =
+            new SparseArray<>(); // guarded by mTabletModeLock
+    private final List<TabletModeChangedListenerRecord> mTempTabletModeChangedListenersToNotify =
+            new ArrayList<>();
+
     // Persistent data store.  Must be locked each time during use.
     private final PersistentDataStore mDataStore = new PersistentDataStore();
 
@@ -227,6 +238,11 @@
     /** Switch code: Lid switch.  When set, lid is shut. */
     public static final int SW_LID = 0x00;
 
+    /** Switch code: Tablet mode switch.
+     * When set, the device is in tablet mode (i.e. no keyboard is connected).
+     */
+    public static final int SW_TABLET_MODE = 0x01;
+
     /** Switch code: Keypad slide.  When set, keyboard is exposed. */
     public static final int SW_KEYPAD_SLIDE = 0x0a;
 
@@ -246,6 +262,7 @@
     public static final int SW_CAMERA_LENS_COVER = 0x09;
 
     public static final int SW_LID_BIT = 1 << SW_LID;
+    public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE;
     public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
     public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT;
     public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT;
@@ -774,6 +791,57 @@
         }
     }
 
+    @Override // Binder call
+    public void registerTabletModeChangedListener(ITabletModeChangedListener listener) {
+        if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE_LISTENER,
+                "registerTabletModeChangedListener()")) {
+            throw new SecurityException("Requires TABLET_MODE_LISTENER permission");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        synchronized (mTabletModeLock) {
+            final int callingPid = Binder.getCallingPid();
+            if (mTabletModeChangedListeners.get(callingPid) != null) {
+                throw new IllegalStateException("The calling process has already registered "
+                        + "a TabletModeChangedListener.");
+            }
+            TabletModeChangedListenerRecord record =
+                    new TabletModeChangedListenerRecord(callingPid, listener);
+            try {
+                IBinder binder = listener.asBinder();
+                binder.linkToDeath(record, 0);
+            } catch (RemoteException ex) {
+                throw new RuntimeException(ex);
+            }
+            mTabletModeChangedListeners.put(callingPid, record);
+        }
+    }
+
+    private void onTabletModeChangedListenerDied(int pid) {
+        synchronized (mTabletModeLock) {
+            mTabletModeChangedListeners.remove(pid);
+        }
+    }
+
+    // Must be called on handler
+    private void deliverTabletModeChanged(long whenNanos, boolean inTabletMode) {
+        mTempTabletModeChangedListenersToNotify.clear();
+        final int numListeners;
+        synchronized (mTabletModeLock) {
+            numListeners = mTabletModeChangedListeners.size();
+            for (int i = 0; i < numListeners; i++) {
+                mTempTabletModeChangedListenersToNotify.add(
+                        mTabletModeChangedListeners.valueAt(i));
+            }
+        }
+        for (int i = 0; i < numListeners; i++) {
+            mTempTabletModeChangedListenersToNotify.get(i).notifyTabletModeChanged(
+                    whenNanos, inTabletMode);
+        }
+    }
+
     // Must be called on handler.
     private void showMissingKeyboardLayoutNotification(InputDevice device) {
         if (!mKeyboardLayoutNotificationShown) {
@@ -1419,6 +1487,15 @@
             mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
                     switchMask);
         }
+
+        if ((switchMask & SW_TABLET_MODE) != 0) {
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
+            args.argi2 = (int) (whenNanos >> 32);
+            args.arg1 = Boolean.valueOf((switchValues & SW_TABLET_MODE_BIT) != 0);
+            mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,
+                    args).sendToTarget();
+        }
     }
 
     // Native callback.
@@ -1664,6 +1741,12 @@
                 case MSG_RELOAD_DEVICE_ALIASES:
                     reloadDeviceAliases();
                     break;
+                case MSG_DELIVER_TABLET_MODE_CHANGED:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32);
+                    boolean inTabletMode = (boolean) args.arg1;
+                    deliverTabletModeChanged(whenNanos, inTabletMode);
+                    break;
             }
         }
     }
@@ -1755,6 +1838,34 @@
         }
     }
 
+    private final class TabletModeChangedListenerRecord implements DeathRecipient {
+        private final int mPid;
+        private final ITabletModeChangedListener mListener;
+
+        public TabletModeChangedListenerRecord(int pid, ITabletModeChangedListener listener) {
+            mPid = pid;
+            mListener = listener;
+        }
+
+        @Override
+        public void binderDied() {
+            if (DEBUG) {
+                Slog.d(TAG, "Tablet mode changed listener for pid " + mPid + " died.");
+            }
+            onTabletModeChangedListenerDied(mPid);
+        }
+
+        public void notifyTabletModeChanged(long whenNanos, boolean inTabletMode) {
+            try {
+                mListener.onTabletModeChanged(whenNanos, inTabletMode);
+            } catch (RemoteException ex) {
+                Slog.w(TAG, "Failed to notify process " + mPid +
+                        " that tablet mode changed, assuming it died.", ex);
+                binderDied();
+            }
+        }
+    }
+
     private final class VibratorToken implements DeathRecipient {
         public final int mDeviceId;
         public final IBinder mToken;
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 239c471..5e5a55c 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -447,7 +447,8 @@
                 checkSmsSuplInit(intent);
             } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
                 checkWapSuplInit(intent);
-            } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+            } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)
+                    || action.equals(ConnectivityManager.CONNECTIVITY_ACTION_SUPL)) {
                 // retrieve NetworkType result for this UID
                 int networkType = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
                 if (DEBUG) Log.d(TAG, "Connectivity action, type=" + networkType);
@@ -2067,6 +2068,7 @@
             intentFilter.addAction(ALARM_WAKEUP);
             intentFilter.addAction(ALARM_TIMEOUT);
             intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
             intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
             intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
             intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 88088fa..82afdd7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5999,12 +5999,6 @@
          */
         if (shouldHideSystemApp) {
             synchronized (mPackages) {
-                /*
-                 * We have to grant systems permissions before we hide, because
-                 * grantPermissions will assume the package update is trying to
-                 * expand its permissions.
-                 */
-                grantPermissionsLPw(pkg, true, pkg.packageName);
                 mSettings.disableSystemPackageLPw(pkg.packageName);
             }
         }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 958a9d5..4d67702 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -65,6 +65,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
+import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -265,6 +266,7 @@
     WindowManagerFuncs mWindowManagerFuncs;
     WindowManagerInternal mWindowManagerInternal;
     PowerManager mPowerManager;
+    PowerManagerInternal mPowerManagerInternal;
     ActivityManagerInternal mActivityManagerInternal;
     DreamManagerInternal mDreamManagerInternal;
     IStatusBarService mStatusBarService;
@@ -1335,6 +1337,7 @@
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
 
         // Init display burn-in protection
         boolean burnInProtectionEnabled = context.getResources().getBoolean(
@@ -5125,6 +5128,15 @@
                 break;
             }
 
+            case KeyEvent.KEYCODE_SOFT_SLEEP: {
+                result &= ~ACTION_PASS_TO_USER;
+                isWakeKey = false;
+                if (!down) {
+                    mPowerManagerInternal.setUserInactiveOverrideFromWindowManager();
+                }
+                break;
+            }
+
             case KeyEvent.KEYCODE_WAKEUP: {
                 result &= ~ACTION_PASS_TO_USER;
                 isWakeKey = true;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 7ebb7f8..4e702aa 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -393,6 +393,10 @@
     // Use -1 to disable.
     private int mScreenBrightnessOverrideFromWindowManager = -1;
 
+    // The window manager has determined the user to be inactive via other means.
+    // Set this to false to disable.
+    private boolean mUserInactiveOverrideFromWindowManager;
+
     // The user activity timeout override from the window manager
     // to allow the current foreground activity to override the user activity timeout.
     // Use -1 to disable.
@@ -1028,6 +1032,10 @@
 
             mNotifier.onUserActivity(event, uid);
 
+            if (mUserInactiveOverrideFromWindowManager) {
+                mUserInactiveOverrideFromWindowManager = false;
+            }
+
             if (mWakefulness == WAKEFULNESS_ASLEEP
                     || mWakefulness == WAKEFULNESS_DOZING
                     || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
@@ -1525,6 +1533,7 @@
                 final int sleepTimeout = getSleepTimeoutLocked();
                 final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
                 final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
+                final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
 
                 mUserActivitySummary = 0;
                 if (mLastUserActivityTime >= mLastWakeTime) {
@@ -1550,6 +1559,7 @@
                         }
                     }
                 }
+
                 if (mUserActivitySummary == 0) {
                     if (sleepTimeout >= 0) {
                         final long anyUserActivity = Math.max(mLastUserActivityTime,
@@ -1565,6 +1575,12 @@
                         nextTimeout = -1;
                     }
                 }
+
+                if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
+                    mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
+                    nextTimeout = -1;
+                }
+
                 if (mUserActivitySummary != 0 && nextTimeout >= 0) {
                     Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
                     msg.setAsynchronous(true);
@@ -2494,6 +2510,14 @@
         }
     }
 
+    private void setUserInactiveOverrideFromWindowManagerInternal() {
+        synchronized (mLock) {
+            mUserInactiveOverrideFromWindowManager = true;
+            mDirty |= DIRTY_USER_ACTIVITY;
+            updatePowerStateLocked();
+        }
+    }
+
     private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
         synchronized (mLock) {
             if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
@@ -2688,6 +2712,8 @@
                     + mScreenBrightnessOverrideFromWindowManager);
             pw.println("  mUserActivityTimeoutOverrideFromWindowManager="
                     + mUserActivityTimeoutOverrideFromWindowManager);
+            pw.println("  mUserInactiveOverrideFromWindowManager="
+                    + mUserInactiveOverrideFromWindowManager);
             pw.println("  mTemporaryScreenBrightnessSettingOverride="
                     + mTemporaryScreenBrightnessSettingOverride);
             pw.println("  mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
@@ -3492,6 +3518,11 @@
         }
 
         @Override
+        public void setUserInactiveOverrideFromWindowManager() {
+            setUserInactiveOverrideFromWindowManagerInternal();
+        }
+
+        @Override
         public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
             setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
         }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a210223..6ee2c39 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -112,6 +112,11 @@
     boolean mLaunchTaskBehind;
     boolean mEnteringAnimation;
 
+    // This application will have its window replaced due to relaunch. This allows window manager
+    // to differentiate between simple removal of a window and replacement. In the latter case it
+    // will preserve the old window until the new one is drawn.
+    boolean mReplacingWindow;
+
     AppWindowToken(WindowManagerService _service, IApplicationToken _token,
             boolean _voiceInteraction) {
         super(_service, _token.asBinder(),
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index d0962f4..fc23fd1 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -750,7 +750,7 @@
     }
 
     boolean adjustWallpaperWindows() {
-        mService.mInnerFields.mWallpaperMayChange = false;
+        mService.mWindowPlacerLocked.mWallpaperMayChange = false;
 
         final WindowList windows = mService.getDefaultWindowListLocked();
         // First find top-most window that has asked to be on top of the wallpaper;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index e6a1be1..b334a05 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -23,11 +23,11 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
+import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
 
 import android.content.Context;
 import android.os.RemoteException;
@@ -41,8 +41,6 @@
 import android.view.animation.Animation;
 import android.view.Choreographer;
 
-import com.android.server.wm.WindowManagerService.LayoutFields;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
@@ -84,8 +82,7 @@
     int mBulkUpdateParams = 0;
     Object mLastWindowFreezeSource;
 
-    SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
-            new SparseArray<DisplayContentsAnimator>(2);
+    SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = new SparseArray<>(2);
 
     boolean mInitialized = false;
 
@@ -179,10 +176,12 @@
                     mAnimating = mAppWindowAnimating = true;
                 } else if (appAnimator.wasAnimating) {
                     // stopped animating, do one more pass through the layout
-                    setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
-                        "exiting appToken " + appAnimator.mAppToken + " done", displayId);
+                    setAppLayoutChanges(appAnimator,
+                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
+                            "exiting appToken " + appAnimator.mAppToken + " done", displayId);
                     if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
-                            "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
+                            "updateWindowsApps...: done animating exiting "
+                                    + appAnimator.mAppToken);
                 }
             }
         }
@@ -301,7 +300,8 @@
                     setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                     if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                        mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2",
+                        mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                "updateWindowsAndWallpaperLocked 2",
                                 getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
                     }
                 }
@@ -315,7 +315,8 @@
                         setPendingLayoutChanges(displayId,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3",
+                            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                    "updateWindowsAndWallpaperLocked 3",
                                     getPendingLayoutChanges(displayId));
                         }
                         mService.mFocusMayChange = true;
@@ -409,7 +410,8 @@
                         setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4",
+                            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                    "updateWindowsAndWallpaperLocked 4",
                                     getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
                         }
                     }
@@ -433,7 +435,8 @@
                         setPendingLayoutChanges(displayId,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
+                            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                                    "updateWindowsAndWallpaperLocked 5",
                                     getPendingLayoutChanges(displayId));
                         }
                     }
@@ -607,7 +610,8 @@
                                     "Setting mOrientationChangeComplete=true because wtoken "
                                     + wtoken + " numInteresting=" + wtoken.numInterestingWindows
                                     + " numDrawn=" + wtoken.numDrawnWindows);
-                            // This will set mOrientationChangeComplete and cause a pass through layout.
+                            // This will set mOrientationChangeComplete and cause a pass through
+                            // layout.
                             setAppLayoutChanges(appAnimator,
                                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
                                     "testTokenMayBeDrawnLocked: freezingScreen", displayId);
@@ -737,7 +741,7 @@
 
         boolean doRequest = false;
         if (mBulkUpdateParams != 0) {
-            doRequest = mService.copyAnimToLayoutParamsLocked();
+            doRequest = mService.mWindowPlacerLocked.copyAnimToLayoutParamsLocked();
         }
 
         if (hasPendingLayoutChanges || doRequest) {
@@ -755,21 +759,21 @@
         }
     }
 
-    static String bulkUpdateParamsToString(int bulkUpdateParams) {
+    private static String bulkUpdateParamsToString(int bulkUpdateParams) {
         StringBuilder builder = new StringBuilder(128);
-        if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
+        if ((bulkUpdateParams & WindowSurfacePlacer.SET_UPDATE_ROTATION) != 0) {
             builder.append(" UPDATE_ROTATION");
         }
-        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
+        if ((bulkUpdateParams & WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE) != 0) {
             builder.append(" WALLPAPER_MAY_CHANGE");
         }
-        if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
+        if ((bulkUpdateParams & WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED) != 0) {
             builder.append(" FORCE_HIDING_CHANGED");
         }
-        if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) != 0) {
+        if ((bulkUpdateParams & WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE) != 0) {
             builder.append(" ORIENTATION_CHANGE_COMPLETE");
         }
-        if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+        if ((bulkUpdateParams & WindowSurfacePlacer.SET_TURN_ON_SCREEN) != 0) {
             builder.append(" TURN_ON_SCREEN");
         }
         return builder.toString();
@@ -846,7 +850,8 @@
             if (displayId == windows.get(i).getDisplayId()) {
                 setPendingLayoutChanges(displayId, changes);
                 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                    mService.debugLayoutRepeats(reason, getPendingLayoutChanges(displayId));
+                    mService.mWindowPlacerLocked.debugLayoutRepeats(reason,
+                            getPendingLayoutChanges(displayId));
                 }
                 break;
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 841233c..ebabc52 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -34,8 +34,6 @@
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -70,7 +68,6 @@
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
-import android.util.IntArray;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -112,7 +109,6 @@
 import android.view.WindowManagerPolicy;
 import android.view.WindowManagerPolicy.PointerEventListener;
 import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
 
 import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 import com.android.internal.app.IAssistScreenshotReceiver;
@@ -157,16 +153,12 @@
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
@@ -177,11 +169,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -313,6 +302,7 @@
             }
         }
     };
+    final WindowSurfacePlacer mWindowPlacerLocked;
 
     /**
      * Current user when multi-user is enabled. Don't show windows of
@@ -341,8 +331,6 @@
 
     final IActivityManager mActivityManager;
 
-    final IBatteryStats mBatteryStats;
-
     final AppOpsManager mAppOps;
 
     final DisplaySettings mDisplaySettings;
@@ -444,7 +432,6 @@
 
     final float[] mTmpFloats = new float[9];
     final Rect mTmpContentRect = new Rect();
-    private final Rect mTmpStartRect = new Rect();
 
     boolean mDisplayReady;
     boolean mSafeMode;
@@ -491,7 +478,7 @@
     final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
     final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
     final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
-    private int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
+    int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
 
     boolean mClientFreezingScreen = false;
     int mAppsFreezingScreen = 0;
@@ -614,51 +601,11 @@
     // For frozen screen animations.
     int mExitAnimId, mEnterAnimId;
 
-    /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
-     * methods. */
-    class LayoutFields {
-        static final int SET_UPDATE_ROTATION                = 1 << 0;
-        static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
-        static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
-        static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 3;
-        static final int SET_TURN_ON_SCREEN                 = 1 << 4;
-        static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 5;
-
-        boolean mWallpaperForceHidingChanged = false;
-        boolean mWallpaperMayChange = false;
-        boolean mOrientationChangeComplete = true;
-        Object mLastWindowFreezeSource = null;
-        private Session mHoldScreen = null;
-        private boolean mObscured = false;
-        private boolean mSyswin = false;
-        private float mScreenBrightness = -1;
-        private float mButtonBrightness = -1;
-        private long mUserActivityTimeout = -1;
-        private boolean mUpdateRotation = false;
-        boolean mWallpaperActionPending = false;
-
-        // Set to true when the display contains content to show the user.
-        // When false, the display manager may choose to mirror or blank the display.
-        boolean mDisplayHasContent = false;
-
-        // Only set while traversing the default display based on its content.
-        // Affects the behavior of mirroring on secondary displays.
-        boolean mObscureApplicationContentOnSecondaryDisplays = false;
-
-        float mPreferredRefreshRate = 0;
-
-        int mPreferredModeId = 0;
-    }
-    final LayoutFields mInnerFields = new LayoutFields();
-
     boolean mAnimationScheduled;
 
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
-    private int mTransactionSequence;
-
-    /** Only do a maximum of 6 repeated layouts. After that quit */
-    private int mLayoutRepeatCount;
+    int mTransactionSequence;
 
     final WindowAnimator mAnimator;
 
@@ -768,7 +715,7 @@
     boolean mInTouchMode;
 
     private ViewServer mViewServer;
-    private final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
+    final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
     boolean mWindowsChanged = false;
 
     public interface WindowChangeListener {
@@ -788,7 +735,7 @@
 
     // List of clients without a transtiton animation that we notify once we are done transitioning
     // since they won't be notified through the app window animator.
-    private final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
+    final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
 
     /** Listener to notify activity manager about app transitions. */
     private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
@@ -866,6 +813,9 @@
         mDisplaySettings = new DisplaySettings();
         mDisplaySettings.readSettingsLocked();
 
+        mWallpaperControllerLocked = new WallpaperController(this);
+        mWindowPlacerLocked = new WindowSurfacePlacer(this);
+
         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
 
         mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
@@ -902,7 +852,6 @@
         mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
 
         mActivityManager = ActivityManagerNative.getDefault();
-        mBatteryStats = BatteryStatsService.getService();
         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
         AppOpsManager.OnOpChangedInternalListener opListener =
                 new AppOpsManager.OnOpChangedInternalListener() {
@@ -953,8 +902,6 @@
 
         updateCircularDisplayMaskIfNeeded();
         showEmulatorDisplayOverlayIfNeeded();
-
-        mWallpaperControllerLocked = new WallpaperController(this);
     }
 
     public InputMonitor getInputMonitor() {
@@ -2118,6 +2065,15 @@
         // If the display is frozen, just remove immediately, since the
         // animation wouldn't be seen.
         if (win.mHasSurface && okToDisplay()) {
+            final AppWindowToken appToken = win.mAppToken;
+            if (appToken != null && appToken.mReplacingWindow) {
+                // This window is going to be replaced. We need to kepp it around until the new one
+                // gets added, then we will get rid of this one.
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Preserving " + win + " until the new one is "
+                        + "added");
+                win.mExiting = true;
+                return;
+            }
             // If we are not currently running the exit animation, we
             // need to see about starting one.
             wasVisible = win.isWinVisibleLw();
@@ -2137,7 +2093,6 @@
                     mAccessibilityController.onWindowTransitionLocked(win, transit);
                 }
             }
-            final AppWindowToken appToken = win.mAppToken;
             final boolean isAnimating = win.mWinAnimator.isAnimating();
             // The starting window is the last window in this app token and it isn't animating.
             // Allow it to be removed now as there is no additional window or animation that will
@@ -2154,7 +2109,7 @@
                 }
                 final boolean focusChanged = updateFocusedWindowLocked(
                         UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
-                performLayoutAndPlaceSurfacesLocked();
+                mWindowPlacerLocked.performSurfacePlacement();
                 if (appToken != null) {
                     appToken.updateReportedVisibilityLocked();
                 }
@@ -2272,14 +2227,14 @@
         final WindowList windows = win.getWindowList();
         if (windows != null) {
             windows.remove(win);
-            if (!mInLayout) {
+            if (!mWindowPlacerLocked.isInLayout()) {
                 assignLayersLocked(windows);
                 final DisplayContent displayContent = win.getDisplayContent();
                 if (displayContent != null) {
                     displayContent.layoutNeeded = true;
                 }
                 if (performLayout) {
-                    performLayoutAndPlaceSurfacesLocked();
+                    mWindowPlacerLocked.performSurfacePlacement();
                 }
                 if (win.mAppToken != null) {
                     win.mAppToken.updateReportedVisibilityLocked();
@@ -2363,7 +2318,7 @@
                     if (displayContent != null) {
                         displayContent.layoutNeeded = true;
                     }
-                    performLayoutAndPlaceSurfacesLocked();
+                    mWindowPlacerLocked.performSurfacePlacement();
                 }
             }
         } finally {
@@ -2692,7 +2647,7 @@
             }
             win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
             configChanged = updateOrientationFromAppTokensLocked(false);
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
             if (toBeDisplayed && win.mIsWallpaper) {
                 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
                 mWallpaperControllerLocked.updateWallpaperOffset(
@@ -3025,7 +2980,7 @@
                     wtoken.hidden = true;
 
                     if (changed) {
-                        performLayoutAndPlaceSurfacesLocked();
+                        mWindowPlacerLocked.performSurfacePlacement();
                         updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
                                 false /*updateInputWindows*/);
                     }
@@ -3391,7 +3346,7 @@
                 mWaitingForConfig = false;
                 mLastFinishedFreezeSource = "new-config";
             }
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -3589,7 +3544,7 @@
                 mAppTransition.setReady();
                 final long origId = Binder.clearCallingIdentity();
                 try {
-                    performLayoutAndPlaceSurfacesLocked();
+                    mWindowPlacerLocked.performSurfacePlacement();
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -3696,7 +3651,7 @@
                         updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
                                 true /*updateInputWindows*/);
                         getDefaultDisplayContentLocked().layoutNeeded = true;
-                        performLayoutAndPlaceSurfacesLocked();
+                        mWindowPlacerLocked.performSurfacePlacement();
                         Binder.restoreCallingIdentity(origId);
                         return;
                     } else if (ttoken.startingData != null) {
@@ -3962,7 +3917,7 @@
                 if (performLayout) {
                     updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
                             false /*updateInputWindows*/);
-                    performLayoutAndPlaceSurfacesLocked();
+                    mWindowPlacerLocked.performSurfacePlacement();
                 }
                 mInputMonitor.updateInputWindowsLw(false /*force*/);
             }
@@ -4100,7 +4055,7 @@
                             && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
                         if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
                         w.mOrientationChanging = true;
-                        mInnerFields.mOrientationChangeComplete = false;
+                        mWindowPlacerLocked.mOrientationChangeComplete = false;
                     }
                     w.mLastFreezeDuration = 0;
                     unfrozeWindows = true;
@@ -4120,7 +4075,7 @@
             }
             if (unfreezeSurfaceNow) {
                 if (unfrozeWindows) {
-                    performLayoutAndPlaceSurfacesLocked();
+                    mWindowPlacerLocked.performSurfacePlacement();
                 }
                 stopFreezingDisplayLocked();
             }
@@ -4408,7 +4363,7 @@
         }
 
         mInputMonitor.setUpdateInputWindowsNeededLw();
-        performLayoutAndPlaceSurfacesLocked();
+        mWindowPlacerLocked.performSurfacePlacement();
         mInputMonitor.updateInputWindowsLw(false /*force*/);
 
         //dump();
@@ -4560,7 +4515,7 @@
             stack.addTask(task, toTop);
             final DisplayContent displayContent = stack.getDisplayContent();
             displayContent.layoutNeeded = true;
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -4581,7 +4536,7 @@
             task.moveTaskToStack(stack, toTop);
             final DisplayContent displayContent = stack.getDisplayContent();
             displayContent.layoutNeeded = true;
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -4616,7 +4571,7 @@
             if (stack.setBounds(bounds, resizeTasks, configs, taskBounds)) {
                 stack.resizeWindows();
                 stack.getDisplayContent().layoutNeeded = true;
-                performLayoutAndPlaceSurfacesLocked();
+                mWindowPlacerLocked.performSurfacePlacement();
             }
             return stack.isFullscreen();
         }
@@ -4641,7 +4596,7 @@
             task.positionTaskInStack(stack, position);
             final DisplayContent displayContent = stack.getDisplayContent();
             displayContent.layoutNeeded = true;
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -4661,7 +4616,7 @@
                 task.resizeWindows();
                 if (relayout) {
                     task.getDisplayContent().layoutNeeded = true;
-                    performLayoutAndPlaceSurfacesLocked();
+                    mWindowPlacerLocked.performSurfacePlacement();
                 }
             }
         }
@@ -5054,7 +5009,7 @@
                 displayContent.switchUserStacks();
                 rebuildAppWindowListLocked(displayContent);
             }
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -5893,7 +5848,7 @@
             changed = updateRotationUncheckedLocked(false);
             if (!changed || forceRelayout) {
                 getDefaultDisplayContentLocked().layoutNeeded = true;
-                performLayoutAndPlaceSurfacesLocked();
+                mWindowPlacerLocked.performSurfacePlacement();
             }
         }
 
@@ -6027,7 +5982,7 @@
             if (w.mHasSurface) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
                 w.mOrientationChanging = true;
-                mInnerFields.mOrientationChangeComplete = false;
+                mWindowPlacerLocked.mOrientationChangeComplete = false;
             }
             w.mLastFreezeDuration = 0;
         }
@@ -7178,7 +7133,7 @@
                 case DO_TRAVERSAL: {
                     synchronized(mWindowMap) {
                         mTraversalScheduled = false;
-                        performLayoutAndPlaceSurfacesLocked();
+                        mWindowPlacerLocked.performSurfacePlacement();
                     }
                 } break;
 
@@ -7350,7 +7305,7 @@
                                 Slog.w(TAG, "Force clearing orientation change: " + w);
                             }
                         }
-                        performLayoutAndPlaceSurfacesLocked();
+                        mWindowPlacerLocked.performSurfacePlacement();
                     }
                     break;
                 }
@@ -7364,7 +7319,7 @@
                                     + " mOpeningApps.size()=" + mOpeningApps.size()
                                     + " mClosingApps.size()=" + mClosingApps.size());
                             mAppTransition.setTimeout();
-                            performLayoutAndPlaceSurfacesLocked();
+                            mWindowPlacerLocked.performSurfacePlacement();
                         }
                     }
                     break;
@@ -7627,7 +7582,7 @@
                 case WALLPAPER_DRAW_PENDING_TIMEOUT: {
                     synchronized (mWindowMap) {
                         if (mWallpaperControllerLocked.processWallpaperDrawPendingTimeout()) {
-                            performLayoutAndPlaceSurfacesLocked();
+                            mWindowPlacerLocked.performSurfacePlacement();
                         }
                     }
                 }
@@ -8019,7 +7974,7 @@
             mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
         }
 
-        performLayoutAndPlaceSurfacesLocked();
+        mWindowPlacerLocked.performSurfacePlacement();
     }
 
     private void configureDisplayPolicyLocked(DisplayContent displayContent) {
@@ -8207,7 +8162,7 @@
         Arrays.fill(mRebuildTmp, null);
     }
 
-    private final void assignLayersLocked(WindowList windows) {
+    final void assignLayersLocked(WindowList windows) {
         int N = windows.size();
         int curBaseLayer = 0;
         int curLayer = 0;
@@ -8277,253 +8232,6 @@
         }
     }
 
-    private final void performLayoutAndPlaceSurfacesLocked() {
-        int loopCount = 6;
-        do {
-            mTraversalScheduled = false;
-            performLayoutAndPlaceSurfacesLockedLoop();
-            mH.removeMessages(H.DO_TRAVERSAL);
-            loopCount--;
-        } while (mTraversalScheduled && loopCount > 0);
-        mInnerFields.mWallpaperActionPending = false;
-    }
-
-    private boolean mInLayout = false;
-    private final void performLayoutAndPlaceSurfacesLockedLoop() {
-        if (mInLayout) {
-            if (DEBUG) {
-                throw new RuntimeException("Recursive call!");
-            }
-            Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
-                    + Debug.getCallers(3));
-            return;
-        }
-
-        if (mWaitingForConfig) {
-            // Our configuration has changed (most likely rotation), but we
-            // don't yet have the complete configuration to report to
-            // applications.  Don't do any window layout until we have it.
-            return;
-        }
-
-        if (!mDisplayReady) {
-            // Not yet initialized, nothing to do.
-            return;
-        }
-
-        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
-        mInLayout = true;
-
-        boolean recoveringMemory = false;
-        if (!mForceRemoves.isEmpty()) {
-            recoveringMemory = true;
-            // Wait a little bit for things to settle down, and off we go.
-            while (!mForceRemoves.isEmpty()) {
-                WindowState ws = mForceRemoves.remove(0);
-                Slog.i(TAG, "Force removing: " + ws);
-                removeWindowInnerLocked(ws);
-            }
-            Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
-            Object tmp = new Object();
-            synchronized (tmp) {
-                try {
-                    tmp.wait(250);
-                } catch (InterruptedException e) {
-                }
-            }
-        }
-
-        try {
-            performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
-
-            mInLayout = false;
-
-            if (needsLayout()) {
-                if (++mLayoutRepeatCount < 6) {
-                    requestTraversalLocked();
-                } else {
-                    Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
-                    mLayoutRepeatCount = 0;
-                }
-            } else {
-                mLayoutRepeatCount = 0;
-            }
-
-            if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
-                mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
-                mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
-            }
-        } catch (RuntimeException e) {
-            mInLayout = false;
-            Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
-        }
-
-        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
-    }
-
-    private final void performLayoutLockedInner(final DisplayContent displayContent,
-                                    boolean initial, boolean updateInputWindows) {
-        if (!displayContent.layoutNeeded) {
-            return;
-        }
-        displayContent.layoutNeeded = false;
-        WindowList windows = displayContent.getWindowList();
-        boolean isDefaultDisplay = displayContent.isDefaultDisplay;
-
-        DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
-
-        if (mInputConsumer != null) {
-            mInputConsumer.layout(dw, dh);
-        }
-
-        final int N = windows.size();
-        int i;
-
-        if (DEBUG_LAYOUT) {
-            Slog.v(TAG, "-------------------------------------");
-            Slog.v(TAG, "performLayout: needed="
-                    + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
-        }
-
-        mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
-        if (isDefaultDisplay) {
-            // Not needed on non-default displays.
-            mSystemDecorLayer = mPolicy.getSystemDecorLayerLw();
-            mScreenRect.set(0, 0, dw, dh);
-        }
-
-        mPolicy.getContentRectLw(mTmpContentRect);
-        displayContent.resize(mTmpContentRect);
-
-        int seq = mLayoutSeq+1;
-        if (seq < 0) seq = 0;
-        mLayoutSeq = seq;
-
-        boolean behindDream = false;
-
-        // First perform layout of any root windows (not attached
-        // to another window).
-        int topAttached = -1;
-        for (i = N-1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
-
-            // Don't do layout of a window if it is not visible, or
-            // soon won't be visible, to avoid wasting time and funky
-            // changes while a window is animating away.
-            final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
-                    || win.isGoneForLayoutLw();
-
-            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
-                Slog.v(TAG, "1ST PASS " + win
-                        + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
-                        + " mLayoutAttached=" + win.mLayoutAttached
-                        + " screen changed=" + win.isConfigChanged());
-                final AppWindowToken atoken = win.mAppToken;
-                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
-                        + win.mViewVisibility + " mRelayoutCalled="
-                        + win.mRelayoutCalled + " hidden="
-                        + win.mRootToken.hidden + " hiddenRequested="
-                        + (atoken != null && atoken.hiddenRequested)
-                        + " mAttachedHidden=" + win.mAttachedHidden);
-                else Slog.v(TAG, "  VIS: mViewVisibility="
-                        + win.mViewVisibility + " mRelayoutCalled="
-                        + win.mRelayoutCalled + " hidden="
-                        + win.mRootToken.hidden + " hiddenRequested="
-                        + (atoken != null && atoken.hiddenRequested)
-                        + " mAttachedHidden=" + win.mAttachedHidden);
-            }
-
-            // If this view is GONE, then skip it -- keep the current
-            // frame, and let the caller know so they can ignore it
-            // if they want.  (We do the normal layout for INVISIBLE
-            // windows, since that means "perform layout as normal,
-            // just don't display").
-            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
-                    || ((win.isConfigChanged() || win.setInsetsChanged()) &&
-                            ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
-                            (win.mHasSurface && win.mAppToken != null &&
-                            win.mAppToken.layoutConfigChanges)))) {
-                if (!win.mLayoutAttached) {
-                    if (initial) {
-                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                        win.mContentChanged = false;
-                    }
-                    if (win.mAttrs.type == TYPE_DREAM) {
-                        // Don't layout windows behind a dream, so that if it
-                        // does stuff like hide the status bar we won't get a
-                        // bad transition when it goes away.
-                        behindDream = true;
-                    }
-                    win.mLayoutNeeded = false;
-                    win.prelayout();
-                    mPolicy.layoutWindowLw(win, null);
-                    win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
-                            + win.mFrame + " mContainingFrame="
-                            + win.mContainingFrame + " mDisplayFrame="
-                            + win.mDisplayFrame);
-                } else {
-                    if (topAttached < 0) topAttached = i;
-                }
-            }
-        }
-
-        boolean attachedBehindDream = false;
-
-        // Now perform layout of attached windows, which usually
-        // depend on the position of the window they are attached to.
-        // XXX does not deal with windows that are attached to windows
-        // that are themselves attached.
-        for (i = topAttached; i >= 0; i--) {
-            final WindowState win = windows.get(i);
-
-            if (win.mLayoutAttached) {
-                if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
-                        + " mHaveFrame=" + win.mHaveFrame
-                        + " mViewVisibility=" + win.mViewVisibility
-                        + " mRelayoutCalled=" + win.mRelayoutCalled);
-                // If this view is GONE, then skip it -- keep the current
-                // frame, and let the caller know so they can ignore it
-                // if they want.  (We do the normal layout for INVISIBLE
-                // windows, since that means "perform layout as normal,
-                // just don't display").
-                if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
-                    continue;
-                }
-                if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
-                        || !win.mHaveFrame || win.mLayoutNeeded) {
-                    if (initial) {
-                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                        win.mContentChanged = false;
-                    }
-                    win.mLayoutNeeded = false;
-                    win.prelayout();
-                    mPolicy.layoutWindowLw(win, win.mAttachedWindow);
-                    win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
-                            + win.mFrame + " mContainingFrame="
-                            + win.mContainingFrame + " mDisplayFrame="
-                            + win.mDisplayFrame);
-                }
-            } else if (win.mAttrs.type == TYPE_DREAM) {
-                // Don't layout windows behind a dream, so that if it
-                // does stuff like hide the status bar we won't get a
-                // bad transition when it goes away.
-                attachedBehindDream = behindDream;
-            }
-        }
-
-        // Window frames may have changed.  Tell the input dispatcher about it.
-        mInputMonitor.setUpdateInputWindowsNeededLw();
-        if (updateInputWindows) {
-            mInputMonitor.updateInputWindowsLw(false /*force*/);
-        }
-
-        mPolicy.finishLayoutLw();
-    }
-
     void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
         // If the screen is currently frozen or off, then keep
         // it frozen/off until this window draws at its new
@@ -8532,7 +8240,7 @@
             if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);
             w.mOrientationChanging = true;
             w.mLastFreezeDuration = 0;
-            mInnerFields.mOrientationChangeComplete = false;
+            mWindowPlacerLocked.mOrientationChangeComplete = false;
             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
                 mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
                 // XXX should probably keep timeout from
@@ -8545,411 +8253,9 @@
     }
 
     /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     * @param windows List of windows on default display.
      * @return bitmap indicating if another pass through layout must be made.
      */
-    public int handleAppTransitionReadyLocked(WindowList windows) {
-        int appsCount = mOpeningApps.size();
-        if (!checkIfTransitionGoodToGo(appsCount)) {
-            return 0;
-        }
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
-        int transit = mAppTransition.getAppTransition();
-        if (mSkipAppTransitionAnimation) {
-            transit = AppTransition.TRANSIT_UNSET;
-        }
-        mSkipAppTransitionAnimation = false;
-        mNoAnimationNotifyOnTransitionFinished.clear();
-
-        mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
-
-        rebuildAppWindowListLocked();
-
-        mInnerFields.mWallpaperMayChange = false;
-
-        // The top-most window will supply the layout params,
-        // and we will determine it below.
-        LayoutParams animLp = null;
-        int bestAnimLayer = -1;
-        boolean fullscreenAnim = false;
-        boolean voiceInteraction = false;
-
-        final WindowState lowerWallpaperTarget =
-                mWallpaperControllerLocked.getLowerWallpaperTarget();
-        final WindowState upperWallpaperTarget =
-                mWallpaperControllerLocked.getUpperWallpaperTarget();
-
-        boolean openingAppHasWallpaper = false;
-        boolean closingAppHasWallpaper = false;
-        final AppWindowToken lowerWallpaperAppToken;
-        final AppWindowToken upperWallpaperAppToken;
-        if (lowerWallpaperTarget == null) {
-            lowerWallpaperAppToken = upperWallpaperAppToken = null;
-        } else {
-            lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
-            upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
-        }
-
-        int i;
-        // Do a first pass through the tokens for two
-        // things:
-        // (1) Determine if both the closing and opening
-        // app token sets are wallpaper targets, in which
-        // case special animations are needed
-        // (since the wallpaper needs to stay static
-        // behind them).
-        // (2) Find the layout params of the top-most
-        // application window in the tokens, which is
-        // what will control the animation theme.
-        final int closingAppsCount = mClosingApps.size();
-        appsCount = closingAppsCount + mOpeningApps.size();
-        for (i = 0; i < appsCount; i++) {
-            final AppWindowToken wtoken;
-            if (i < closingAppsCount) {
-                wtoken = mClosingApps.valueAt(i);
-                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
-                    closingAppHasWallpaper = true;
-                }
-            } else {
-                wtoken = mOpeningApps.valueAt(i - closingAppsCount);
-                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
-                    openingAppHasWallpaper = true;
-                }
-            }
-
-            voiceInteraction |= wtoken.voiceInteraction;
-
-            if (wtoken.appFullscreen) {
-                WindowState ws = wtoken.findMainWindow();
-                if (ws != null) {
-                    animLp = ws.mAttrs;
-                    bestAnimLayer = ws.mLayer;
-                    fullscreenAnim = true;
-                }
-            } else if (!fullscreenAnim) {
-                WindowState ws = wtoken.findMainWindow();
-                if (ws != null) {
-                    if (ws.mLayer > bestAnimLayer) {
-                        animLp = ws.mAttrs;
-                        bestAnimLayer = ws.mLayer;
-                    }
-                }
-            }
-        }
-
-        transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
-                closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
-
-        // If all closing windows are obscured, then there is
-        // no need to do an animation.  This is the case, for
-        // example, when this transition is being done behind
-        // the lock screen.
-        if (!mPolicy.allowAppAnimationsLw()) {
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "Animations disallowed by keyguard or dream.");
-            animLp = null;
-        }
-
-        processApplicationsAnimatingInPlace(transit);
-
-        AppWindowToken topClosingApp = null;
-        int topClosingLayer = 0;
-        appsCount = mClosingApps.size();
-        for (i = 0; i < appsCount; i++) {
-            AppWindowToken wtoken = mClosingApps.valueAt(i);
-            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
-            appAnimator.clearThumbnail();
-            appAnimator.animation = null;
-            wtoken.inPendingTransaction = false;
-            setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction);
-            wtoken.updateReportedVisibilityLocked();
-            // Force the allDrawn flag, because we want to start
-            // this guy's animations regardless of whether it's
-            // gotten drawn.
-            wtoken.allDrawn = true;
-            wtoken.deferClearAllDrawn = false;
-            // Ensure that apps that are mid-starting are also scheduled to have their
-            // starting windows removed after the animation is complete
-            if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
-                scheduleRemoveStartingWindowLocked(wtoken);
-            }
-            mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
-            if (animLp != null) {
-                int layer = -1;
-                for (int j = 0; j < wtoken.windows.size(); j++) {
-                    WindowState win = wtoken.windows.get(j);
-                    if (win.mWinAnimator.mAnimLayer > layer) {
-                        layer = win.mWinAnimator.mAnimLayer;
-                    }
-                }
-                if (topClosingApp == null || layer > topClosingLayer) {
-                    topClosingApp = wtoken;
-                    topClosingLayer = layer;
-                }
-            }
-        }
-
-        AppWindowToken topOpeningApp = null;
-        appsCount = mOpeningApps.size();
-        for (i = 0; i < appsCount; i++) {
-            AppWindowToken wtoken = mOpeningApps.valueAt(i);
-            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
-
-            if (!appAnimator.usingTransferredAnimation) {
-                appAnimator.clearThumbnail();
-                appAnimator.animation = null;
-            }
-            wtoken.inPendingTransaction = false;
-            if (!setTokenVisibilityLocked(
-                    wtoken, animLp, true, transit, false, voiceInteraction)){
-                // This token isn't going to be animating. Add it to the list of tokens to
-                // be notified of app transition complete since the notification will not be
-                // sent be the app window animator.
-                mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
-            }
-            wtoken.updateReportedVisibilityLocked();
-            wtoken.waitingToShow = false;
-
-            appAnimator.mAllAppWinAnimators.clear();
-            final int windowsCount = wtoken.allAppWindows.size();
-            for (int j = 0; j < windowsCount; j++) {
-                appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
-            }
-            mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
-            mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
-            int topOpeningLayer = 0;
-            if (animLp != null) {
-                int layer = -1;
-                for (int j = 0; j < wtoken.windows.size(); j++) {
-                    WindowState win = wtoken.windows.get(j);
-                    if (win.mWinAnimator.mAnimLayer > layer) {
-                        layer = win.mWinAnimator.mAnimLayer;
-                    }
-                }
-                if (topOpeningApp == null || layer > topOpeningLayer) {
-                    topOpeningApp = wtoken;
-                    topOpeningLayer = layer;
-                }
-            }
-            createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
-        }
-
-        AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
-                topOpeningApp.mAppAnimator;
-        AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
-                topClosingApp.mAppAnimator;
-
-        mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
-        mAppTransition.postAnimationCallback();
-        mAppTransition.clear();
-
-        mOpeningApps.clear();
-        mClosingApps.clear();
-
-        // This has changed the visibility of windows, so perform
-        // a new layout to get them all up-to-date.
-        getDefaultDisplayContentLocked().layoutNeeded = true;
-
-        // TODO(multidisplay): IMEs are only supported on the default display.
-        if (windows == getDefaultWindowListLocked()
-                && !moveInputMethodWindowsIfNeededLocked(true)) {
-            assignLayersLocked(windows);
-        }
-        updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/);
-        mFocusMayChange = false;
-        notifyActivityDrawnForKeyguard();
-        return WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
-                | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
-
-    }
-
-    private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
-            boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
-            WindowState upperWallpaperTarget) {
-        // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
-        final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
-        final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
-                ? null : wallpaperTarget;
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                "New wallpaper target=" + wallpaperTarget
-                        + ", oldWallpaper=" + oldWallpaper
-                        + ", lower target=" + lowerWallpaperTarget
-                        + ", upper target=" + upperWallpaperTarget);
-        mAnimateWallpaperWithTarget = false;
-        if (closingAppHasWallpaper && openingAppHasWallpaper) {
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
-            switch (transit) {
-                case AppTransition.TRANSIT_ACTIVITY_OPEN:
-                case AppTransition.TRANSIT_TASK_OPEN:
-                case AppTransition.TRANSIT_TASK_TO_FRONT:
-                    transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
-                    break;
-                case AppTransition.TRANSIT_ACTIVITY_CLOSE:
-                case AppTransition.TRANSIT_TASK_CLOSE:
-                case AppTransition.TRANSIT_TASK_TO_BACK:
-                    transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
-                    break;
-            }
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "New transit: " + AppTransition.appTransitionToString(transit));
-        } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
-                && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
-            // We are transitioning from an activity with
-            // a wallpaper to one without.
-            transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "New transit away from wallpaper: "
-                    + AppTransition.appTransitionToString(transit));
-        } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()) {
-            // We are transitioning from an activity without
-            // a wallpaper to now showing the wallpaper
-            transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "New transit into wallpaper: "
-                    + AppTransition.appTransitionToString(transit));
-        } else {
-            mAnimateWallpaperWithTarget = true;
-        }
-        return transit;
-    }
-
-    private void processApplicationsAnimatingInPlace(int transit) {
-        if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
-            // Find the focused window
-            final WindowState win =
-                    findFocusedWindowLocked(getDefaultDisplayContentLocked());
-            if (win != null) {
-                final AppWindowToken wtoken = win.mAppToken;
-                final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now animating app in place " + wtoken);
-                appAnimator.clearThumbnail();
-                appAnimator.animation = null;
-                updateTokenInPlaceLocked(wtoken, transit);
-                wtoken.updateReportedVisibilityLocked();
-
-                appAnimator.mAllAppWinAnimators.clear();
-                final int N = wtoken.allAppWindows.size();
-                for (int j = 0; j < N; j++) {
-                    appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
-                }
-                mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-                mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
-            }
-        }
-    }
-
-    private boolean checkIfTransitionGoodToGo(int appsCount) {
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                "Checking " + appsCount + " opening apps (frozen="
-                        + mDisplayFrozen + " timeout="
-                        + mAppTransition.isTimeout() + ")...");
-        if (!mAppTransition.isTimeout()) {
-            for (int i = 0; i < appsCount; i++) {
-                AppWindowToken wtoken = mOpeningApps.valueAt(i);
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                        "Check opening app=" + wtoken + ": allDrawn="
-                        + wtoken.allDrawn + " startingDisplayed="
-                        + wtoken.startingDisplayed + " startingMoved="
-                        + wtoken.startingMoved);
-                if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
-                    return false;
-                }
-            }
-
-            // If the wallpaper is visible, we need to check it's ready too.
-            return !mWallpaperControllerLocked.isWallpaperVisible() ||
-                    mWallpaperControllerLocked.wallpaperTransitionReady();
-        }
-        return true;
-    }
-
-    private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
-            int openingLayer, int closingLayer) {
-        AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
-        if (openingAppAnimator == null || openingAppAnimator.animation == null) {
-            return;
-        }
-        final int taskId = appToken.mTask.mTaskId;
-        Bitmap thumbnailHeader = mAppTransition.getAppTransitionThumbnailHeader(taskId);
-        if (thumbnailHeader == null || thumbnailHeader.getConfig() == Config.ALPHA_8) {
-            return;
-        }
-        // This thumbnail animation is very special, we need to have
-        // an extra surface with the thumbnail included with the animation.
-        Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
-        try {
-            // TODO(multi-display): support other displays
-            final DisplayContent displayContent = getDefaultDisplayContentLocked();
-            final Display display = displayContent.getDisplay();
-            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-
-            // Create a new surface for the thumbnail
-            SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
-                    "thumbnail anim", dirty.width(), dirty.height(),
-                    PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-            surfaceControl.setLayerStack(display.getLayerStack());
-            if (SHOW_TRANSACTIONS) {
-                Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
-            }
-
-            // Draw the thumbnail onto the surface
-            Surface drawSurface = new Surface();
-            drawSurface.copyFrom(surfaceControl);
-            Canvas c = drawSurface.lockCanvas(dirty);
-            c.drawBitmap(thumbnailHeader, 0, 0, null);
-            drawSurface.unlockCanvasAndPost(c);
-            drawSurface.release();
-
-            // Get the thumbnail animation
-            Animation anim;
-            if (mAppTransition.isNextThumbnailTransitionAspectScaled()) {
-                // If this is a multi-window scenario, we use the windows frame as
-                // destination of the thumbnail header animation. If this is a full screen
-                // window scenario, we use the whole display as the target.
-                WindowState win = appToken.findMainWindow();
-                Rect appRect = win != null ? win.getContentFrameLw() :
-                        new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
-                // For the new aspect-scaled transition, we want it to always show
-                // above the animating opening/closing window, and we want to
-                // synchronize its thumbnail surface with the surface for the
-                // open/close animation (only on the way down)
-                anim = mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
-                        thumbnailHeader, taskId);
-                Log.d(TAG, "assigning thumbnail force above layer: " + openingLayer + " " +
-                        closingLayer);
-                openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
-                openingAppAnimator.deferThumbnailDestruction =
-                        !mAppTransition.isNextThumbnailTransitionScaleUp();
-            } else {
-                anim = mAppTransition.createThumbnailScaleAnimationLocked(
-                        displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
-            }
-            anim.restrictDuration(MAX_ANIMATION_DURATION);
-            anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
-
-            openingAppAnimator.thumbnail = surfaceControl;
-            openingAppAnimator.thumbnailLayer = openingLayer;
-            openingAppAnimator.thumbnailAnimation = anim;
-            mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
-            openingAppAnimator.thumbnailX = mTmpStartRect.left;
-            openingAppAnimator.thumbnailY = mTmpStartRect.top;
-        } catch (OutOfResourcesException e) {
-            Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
-                    + " h=" + dirty.height(), e);
-            openingAppAnimator.clearThumbnail();
-        }
-    }
-
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     * @return bitmap indicating if another pass through layout must be made.
-     */
-    private int handleAnimatingStoppedAndTransitionLocked() {
+    int handleAnimatingStoppedAndTransitionLocked() {
         int changes = 0;
 
         mAppTransition.setIdle();
@@ -8979,7 +8285,7 @@
         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
                 "Wallpaper layer changed: assigning layers + relayout");
         moveInputMethodWindowsIfNeededLocked(true);
-        mInnerFields.mWallpaperMayChange = true;
+        mWindowPlacerLocked.mWallpaperMayChange = true;
         // Since the window list has been rebuilt, focus might
         // have to be recomputed since the actual order of windows
         // might have changed again.
@@ -8988,7 +8294,7 @@
         return changes;
     }
 
-    private void updateResizingWindows(final WindowState w) {
+    void updateResizingWindows(final WindowState w) {
         final WindowStateAnimator winAnimator = w.mWinAnimator;
         if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
             w.setInsetsChanged();
@@ -9060,707 +8366,6 @@
         }
     }
 
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     * @param w WindowState this method is applied to.
-     * @param innerDw Width of app window.
-     * @param innerDh Height of app window.
-     */
-    private void handleNotObscuredLocked(final WindowState w,
-            final int innerDw, final int innerDh) {
-        final WindowManager.LayoutParams attrs = w.mAttrs;
-        final int attrFlags = attrs.flags;
-        final boolean canBeSeen = w.isDisplayedLw();
-        final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
-
-        if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
-            // This window completely covers everything behind it,
-            // so we want to leave all of them as undimmed (for
-            // performance reasons).
-            mInnerFields.mObscured = true;
-        }
-
-        if (w.mHasSurface) {
-            if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
-                mInnerFields.mHoldScreen = w.mSession;
-            }
-            if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
-                    && mInnerFields.mScreenBrightness < 0) {
-                mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
-            }
-            if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
-                    && mInnerFields.mButtonBrightness < 0) {
-                mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
-            }
-            if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
-                    && mInnerFields.mUserActivityTimeout < 0) {
-                mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
-            }
-
-            final int type = attrs.type;
-            if (canBeSeen
-                    && (type == TYPE_SYSTEM_DIALOG
-                     || type == TYPE_SYSTEM_ERROR
-                     || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
-                mInnerFields.mSyswin = true;
-            }
-
-            if (canBeSeen) {
-                // This function assumes that the contents of the default display are
-                // processed first before secondary displays.
-                final DisplayContent displayContent = w.getDisplayContent();
-                if (displayContent != null && displayContent.isDefaultDisplay) {
-                    // While a dream or keyguard is showing, obscure ordinary application
-                    // content on secondary displays (by forcibly enabling mirroring unless
-                    // there is other content we want to show) but still allow opaque
-                    // keyguard dialogs to be shown.
-                    if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-                        mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
-                    }
-                    mInnerFields.mDisplayHasContent = true;
-                } else if (displayContent != null &&
-                        (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
-                        || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) {
-                    // Allow full screen keyguard presentation dialogs to be seen.
-                    mInnerFields.mDisplayHasContent = true;
-                }
-                if (mInnerFields.mPreferredRefreshRate == 0
-                        && w.mAttrs.preferredRefreshRate != 0) {
-                    mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
-                }
-                if (mInnerFields.mPreferredModeId == 0
-                        && w.mAttrs.preferredDisplayModeId != 0) {
-                    mInnerFields.mPreferredModeId = w.mAttrs.preferredDisplayModeId;
-                }
-            }
-        }
-    }
-
-    private void handleFlagDimBehind(WindowState w) {
-        final WindowManager.LayoutParams attrs = w.mAttrs;
-        if ((attrs.flags & FLAG_DIM_BEHIND) != 0
-                && w.isDisplayedLw()
-                && !w.mExiting) {
-            final WindowStateAnimator winAnimator = w.mWinAnimator;
-            final Task task = w.getTask();
-            if (task == null) {
-                return;
-            }
-            task.setContinueDimming();
-            if (!task.isDimming(winAnimator)) {
-                if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
-                task.startDimmingIfNeeded(winAnimator);
-            }
-        }
-    }
-
-    private void updateAllDrawnLocked(DisplayContent displayContent) {
-        // See if any windows have been drawn, so they (and others
-        // associated with them) can now be shown.
-        ArrayList<TaskStack> stacks = displayContent.getStacks();
-        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
-            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
-                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
-                    final AppWindowToken wtoken = tokens.get(tokenNdx);
-                    if (!wtoken.allDrawn) {
-                        int numInteresting = wtoken.numInterestingWindows;
-                        if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                            if (DEBUG_VISIBILITY) Slog.v(TAG,
-                                    "allDrawn: " + wtoken
-                                    + " interesting=" + numInteresting
-                                    + " drawn=" + wtoken.numDrawnWindows);
-                            wtoken.allDrawn = true;
-                            // Force an additional layout pass where WindowStateAnimator#
-                            // commitFinishDrawingLocked() will call performShowLocked().
-                            displayContent.layoutNeeded = true;
-                            mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // "Something has changed!  Let's make it correct now."
-    private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
-        if (DEBUG_WINDOW_TRACE) {
-            Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
-                    + Debug.getCallers(3));
-        }
-
-        int i;
-        boolean updateInputWindowsNeeded = false;
-
-        if (mFocusMayChange) {
-            mFocusMayChange = false;
-            updateInputWindowsNeeded = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-                    false /*updateInputWindows*/);
-        }
-
-        // Initialize state of exiting tokens.
-        final int numDisplays = mDisplayContents.size();
-        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-            for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
-                displayContent.mExitingTokens.get(i).hasVisible = false;
-            }
-        }
-
-        for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
-            // Initialize state of exiting applications.
-            final AppTokenList exitingAppTokens =
-                    mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
-            for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
-                exitingAppTokens.get(tokenNdx).hasVisible = false;
-            }
-        }
-
-        mInnerFields.mHoldScreen = null;
-        mInnerFields.mScreenBrightness = -1;
-        mInnerFields.mButtonBrightness = -1;
-        mInnerFields.mUserActivityTimeout = -1;
-        mInnerFields.mObscureApplicationContentOnSecondaryDisplays = false;
-
-        mTransactionSequence++;
-
-        final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
-        final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
-        final int defaultDw = defaultInfo.logicalWidth;
-        final int defaultDh = defaultInfo.logicalHeight;
-
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
-        SurfaceControl.openTransaction();
-        try {
-
-            if (mWatermark != null) {
-                mWatermark.positionSurface(defaultDw, defaultDh);
-            }
-            if (mStrictModeFlash != null) {
-                mStrictModeFlash.positionSurface(defaultDw, defaultDh);
-            }
-            if (mCircularDisplayMask != null) {
-                mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mRotation);
-            }
-            if (mEmulatorDisplayOverlay != null) {
-                mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh, mRotation);
-            }
-
-            boolean focusDisplayed = false;
-
-            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-                boolean updateAllDrawn = false;
-                WindowList windows = displayContent.getWindowList();
-                DisplayInfo displayInfo = displayContent.getDisplayInfo();
-                final int displayId = displayContent.getDisplayId();
-                final int dw = displayInfo.logicalWidth;
-                final int dh = displayInfo.logicalHeight;
-                final int innerDw = displayInfo.appWidth;
-                final int innerDh = displayInfo.appHeight;
-                final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-
-                // Reset for each display.
-                mInnerFields.mDisplayHasContent = false;
-                mInnerFields.mPreferredRefreshRate = 0;
-                mInnerFields.mPreferredModeId = 0;
-
-                int repeats = 0;
-                do {
-                    repeats++;
-                    if (repeats > 6) {
-                        Slog.w(TAG, "Animation repeat aborted after too many iterations");
-                        displayContent.layoutNeeded = false;
-                        break;
-                    }
-
-                    if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
-                        displayContent.pendingLayoutChanges);
-
-                    if ((displayContent.pendingLayoutChanges &
-                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
-                            mWallpaperControllerLocked.adjustWallpaperWindows()) {
-                        assignLayersLocked(windows);
-                        displayContent.layoutNeeded = true;
-                    }
-
-                    if (isDefaultDisplay && (displayContent.pendingLayoutChanges
-                            & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
-                        if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
-                        if (updateOrientationFromAppTokensLocked(true)) {
-                            displayContent.layoutNeeded = true;
-                            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
-                        }
-                    }
-
-                    if ((displayContent.pendingLayoutChanges
-                            & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
-                        displayContent.layoutNeeded = true;
-                    }
-
-                    // FIRST LOOP: Perform a layout, if needed.
-                    if (repeats < LAYOUT_REPEAT_THRESHOLD) {
-                        performLayoutLockedInner(displayContent, repeats == 1,
-                                false /*updateInputWindows*/);
-                    } else {
-                        Slog.w(TAG, "Layout repeat skipped after too many iterations");
-                    }
-
-                    // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
-                    // it is animating.
-                    displayContent.pendingLayoutChanges = 0;
-
-                    if (isDefaultDisplay) {
-                        mPolicy.beginPostLayoutPolicyLw(dw, dh);
-                        for (i = windows.size() - 1; i >= 0; i--) {
-                            WindowState w = windows.get(i);
-                            if (w.mHasSurface) {
-                                mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.mAttachedWindow);
-                            }
-                        }
-                        displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
-                        if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
-                            "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
-                    }
-                } while (displayContent.pendingLayoutChanges != 0);
-
-                mInnerFields.mObscured = false;
-                mInnerFields.mSyswin = false;
-                displayContent.resetDimming();
-
-                // Only used if default window
-                final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
-
-                final int N = windows.size();
-                for (i=N-1; i>=0; i--) {
-                    WindowState w = windows.get(i);
-                    final Task task = w.getTask();
-                    if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
-                        continue;
-                    }
-
-                    final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
-
-                    // Update effect.
-                    w.mObscured = mInnerFields.mObscured;
-                    if (!mInnerFields.mObscured) {
-                        handleNotObscuredLocked(w, innerDw, innerDh);
-                    }
-
-                    if (task != null && !task.getContinueDimming()) {
-                        handleFlagDimBehind(w);
-                    }
-
-                    if (isDefaultDisplay && obscuredChanged
-                            && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
-                        // This is the wallpaper target and its obscured state
-                        // changed... make sure the current wallaper's visibility
-                        // has been updated accordingly.
-                        mWallpaperControllerLocked.updateWallpaperVisibility();
-                    }
-
-                    final WindowStateAnimator winAnimator = w.mWinAnimator;
-
-                    // If the window has moved due to its containing content frame changing, then
-                    // notify the listeners and optionally animate it.
-                    if (w.hasMoved()) {
-                        // Frame has moved, containing content frame has also moved, and we're not
-                        // currently animating... let's do something.
-                        final int left = w.mFrame.left;
-                        final int top = w.mFrame.top;
-                        if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
-                            Animation a = AnimationUtils.loadAnimation(mContext,
-                                    com.android.internal.R.anim.window_move_from_decor);
-                            winAnimator.setAnimation(a);
-                            winAnimator.mAnimDw = w.mLastFrame.left - left;
-                            winAnimator.mAnimDh = w.mLastFrame.top - top;
-                            winAnimator.mAnimateMove = true;
-                            winAnimator.mAnimatingMove = true;
-                        }
-
-                        //TODO (multidisplay): Accessibility supported only for the default display.
-                        if (mAccessibilityController != null
-                                && displayId == Display.DEFAULT_DISPLAY) {
-                            mAccessibilityController.onSomeWindowResizedOrMovedLocked();
-                        }
-
-                        try {
-                            w.mClient.moved(left, top);
-                        } catch (RemoteException e) {
-                        }
-                    }
-
-                    //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
-                    w.mContentChanged = false;
-
-                    // Moved from updateWindowsAndWallpaperLocked().
-                    if (w.mHasSurface) {
-                        // Take care of the window being ready to display.
-                        final boolean committed =
-                                winAnimator.commitFinishDrawingLocked();
-                        if (isDefaultDisplay && committed) {
-                            if (w.mAttrs.type == TYPE_DREAM) {
-                                // HACK: When a dream is shown, it may at that
-                                // point hide the lock screen.  So we need to
-                                // redo the layout to let the phone window manager
-                                // make this happen.
-                                displayContent.pendingLayoutChanges |=
-                                        WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
-                                if (DEBUG_LAYOUT_REPEATS) {
-                                    debugLayoutRepeats(
-                                            "dream and commitFinishDrawingLocked true",
-                                            displayContent.pendingLayoutChanges);
-                                }
-                            }
-                            if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
-                                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                                            "First draw done in potential wallpaper target " + w);
-                                mInnerFields.mWallpaperMayChange = true;
-                                displayContent.pendingLayoutChanges |=
-                                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                                if (DEBUG_LAYOUT_REPEATS) {
-                                    debugLayoutRepeats(
-                                            "wallpaper and commitFinishDrawingLocked true",
-                                            displayContent.pendingLayoutChanges);
-                                }
-                            }
-                        }
-
-                        winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
-                    }
-
-                    final AppWindowToken atoken = w.mAppToken;
-                    if (DEBUG_STARTING_WINDOW && atoken != null
-                            && w == atoken.startingWindow) {
-                        Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
-                            + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
-                            + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
-                    }
-                    if (atoken != null
-                            && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
-                        if (atoken.lastTransactionSequence != mTransactionSequence) {
-                            atoken.lastTransactionSequence = mTransactionSequence;
-                            atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
-                            atoken.startingDisplayed = false;
-                        }
-                        if ((w.isOnScreenIgnoringKeyguard()
-                                || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
-                                && !w.mExiting && !w.mDestroying) {
-                            if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
-                                Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
-                                        + ", isAnimating=" + winAnimator.isAnimating());
-                                if (!w.isDrawnLw()) {
-                                    Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
-                                            + " pv=" + w.mPolicyVisibility
-                                            + " mDrawState=" + winAnimator.drawStateToString()
-                                            + " ah=" + w.mAttachedHidden
-                                            + " th=" + atoken.hiddenRequested
-                                            + " a=" + winAnimator.mAnimating);
-                                }
-                            }
-                            if (w != atoken.startingWindow) {
-                                if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
-                                    atoken.numInterestingWindows++;
-                                    if (w.isDrawnLw()) {
-                                        atoken.numDrawnWindows++;
-                                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
-                                                "tokenMayBeDrawn: " + atoken
-                                                + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
-                                                + " mAppFreezing=" + w.mAppFreezing);
-                                        updateAllDrawn = true;
-                                    }
-                                }
-                            } else if (w.isDrawnLw()) {
-                                atoken.startingDisplayed = true;
-                            }
-                        }
-                    }
-
-                    if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
-                            && w.isDisplayedLw()) {
-                        focusDisplayed = true;
-                    }
-
-                    updateResizingWindows(w);
-                }
-
-                mDisplayManagerInternal.setDisplayProperties(displayId,
-                        mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate,
-                        mInnerFields.mPreferredModeId,
-                        true /* inTraversal, must call performTraversalInTrans... below */);
-
-                getDisplayContentLocked(displayId).stopDimmingIfNeeded();
-
-                if (updateAllDrawn) {
-                    updateAllDrawnLocked(displayContent);
-                }
-            }
-
-            if (focusDisplayed) {
-                mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
-            }
-
-            // Give the display manager a chance to adjust properties
-            // like display rotation if it needs to.
-            mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
-
-        } catch (RuntimeException e) {
-            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
-        } finally {
-            SurfaceControl.closeTransaction();
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
-        }
-
-        final WindowList defaultWindows = defaultDisplay.getWindowList();
-
-        // If we are ready to perform an app transition, check through
-        // all of the app tokens to be shown and see if they are ready
-        // to go.
-        if (mAppTransition.isReady()) {
-            defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
-            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
-                    defaultDisplay.pendingLayoutChanges);
-        }
-
-        if (!mAnimator.mAppWindowAnimating && mAppTransition.isRunning()) {
-            // We have finished the animation of an app transition.  To do
-            // this, we have delayed a lot of operations like showing and
-            // hiding apps, moving apps in Z-order, etc.  The app token list
-            // reflects the correct Z-order, but the window list may now
-            // be out of sync with it.  So here we will just rebuild the
-            // entire app window list.  Fun!
-            defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
-            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
-                defaultDisplay.pendingLayoutChanges);
-        }
-
-        if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
-                && !mAppTransition.isReady()) {
-            // At this point, there was a window with a wallpaper that
-            // was force hiding other windows behind it, but now it
-            // is going away.  This may be simple -- just animate
-            // away the wallpaper and its window -- or it may be
-            // hard -- the wallpaper now needs to be shown behind
-            // something that was hidden.
-            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
-            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
-                defaultDisplay.pendingLayoutChanges);
-        }
-        mInnerFields.mWallpaperForceHidingChanged = false;
-
-        if (mInnerFields.mWallpaperMayChange) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change!  Adjusting");
-            defaultDisplay.pendingLayoutChanges |=
-                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
-                    defaultDisplay.pendingLayoutChanges);
-        }
-
-        if (mFocusMayChange) {
-            mFocusMayChange = false;
-            if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
-                    false /*updateInputWindows*/)) {
-                updateInputWindowsNeeded = true;
-                defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
-            }
-        }
-
-        if (needsLayout()) {
-            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
-            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
-                    defaultDisplay.pendingLayoutChanges);
-        }
-
-        for (i = mResizingWindows.size() - 1; i >= 0; i--) {
-            WindowState win = mResizingWindows.get(i);
-            if (win.mAppFreezing) {
-                // Don't remove this window until rotation has completed.
-                continue;
-            }
-            win.reportResized();
-            mResizingWindows.remove(i);
-        }
-
-        if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
-                "With display frozen, orientationChangeComplete="
-                + mInnerFields.mOrientationChangeComplete);
-        if (mInnerFields.mOrientationChangeComplete) {
-            if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
-                mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
-                mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
-                mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
-            }
-            stopFreezingDisplayLocked();
-        }
-
-        // Destroy the surface of any windows that are no longer visible.
-        boolean wallpaperDestroyed = false;
-        i = mDestroySurface.size();
-        if (i > 0) {
-            do {
-                i--;
-                WindowState win = mDestroySurface.get(i);
-                win.mDestroying = false;
-                if (mInputMethodWindow == win) {
-                    mInputMethodWindow = null;
-                }
-                if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
-                    wallpaperDestroyed = true;
-                }
-                win.mWinAnimator.destroySurfaceLocked();
-            } while (i > 0);
-            mDestroySurface.clear();
-        }
-
-        // Time to remove any exiting tokens?
-        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-            ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
-            for (i = exitingTokens.size() - 1; i >= 0; i--) {
-                WindowToken token = exitingTokens.get(i);
-                if (!token.hasVisible) {
-                    exitingTokens.remove(i);
-                    if (token.windowType == TYPE_WALLPAPER) {
-                        mWallpaperControllerLocked.removeWallpaperToken(token);
-                    }
-                }
-            }
-        }
-
-        // Time to remove any exiting applications?
-        for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
-            // Initialize state of exiting applications.
-            final AppTokenList exitingAppTokens =
-                    mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
-            for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
-                AppWindowToken token = exitingAppTokens.get(i);
-                if (!token.hasVisible && !mClosingApps.contains(token) &&
-                        (!token.mIsExiting || token.allAppWindows.isEmpty())) {
-                    // Make sure there is no animation running on this token,
-                    // so any windows associated with it will be removed as
-                    // soon as their animations are complete
-                    token.mAppAnimator.clearAnimation();
-                    token.mAppAnimator.animating = false;
-                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
-                            "performLayout: App token exiting now removed" + token);
-                    token.removeAppFromTaskLocked();
-                }
-            }
-        }
-
-        if (wallpaperDestroyed) {
-            defaultDisplay.pendingLayoutChanges |=
-                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-            defaultDisplay.layoutNeeded = true;
-        }
-
-        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-            if (displayContent.pendingLayoutChanges != 0) {
-                displayContent.layoutNeeded = true;
-            }
-        }
-
-        // Finally update all input windows now that the window changes have stabilized.
-        mInputMonitor.updateInputWindowsLw(true /*force*/);
-
-        setHoldScreenLocked(mInnerFields.mHoldScreen);
-        if (!mDisplayFrozen) {
-            if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
-                mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
-            } else {
-                mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
-                        toBrightnessOverride(mInnerFields.mScreenBrightness));
-            }
-            if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
-                mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
-            } else {
-                mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
-                        toBrightnessOverride(mInnerFields.mButtonBrightness));
-            }
-            mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
-                    mInnerFields.mUserActivityTimeout);
-        }
-
-        if (mTurnOnScreen) {
-            if (mAllowTheaterModeWakeFromLayout
-                    || Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.THEATER_MODE_ON, 0) == 0) {
-                if (DEBUG_VISIBILITY || DEBUG_POWER) {
-                    Slog.v(TAG, "Turning screen on after layout!");
-                }
-                mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.wm:TURN_ON");
-            }
-            mTurnOnScreen = false;
-        }
-
-        if (mInnerFields.mUpdateRotation) {
-            if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
-            if (updateRotationUncheckedLocked(false)) {
-                mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
-            } else {
-                mInnerFields.mUpdateRotation = false;
-            }
-        }
-
-        if (mWaitingForDrawnCallback != null ||
-                (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
-                        !mInnerFields.mUpdateRotation)) {
-            checkDrawnWindowsLocked();
-        }
-
-        final int N = mPendingRemove.size();
-        if (N > 0) {
-            if (mPendingRemoveTmp.length < N) {
-                mPendingRemoveTmp = new WindowState[N+10];
-            }
-            mPendingRemove.toArray(mPendingRemoveTmp);
-            mPendingRemove.clear();
-            DisplayContentList displayList = new DisplayContentList();
-            for (i = 0; i < N; i++) {
-                WindowState w = mPendingRemoveTmp[i];
-                removeWindowInnerLocked(w);
-                final DisplayContent displayContent = w.getDisplayContent();
-                if (displayContent != null && !displayList.contains(displayContent)) {
-                    displayList.add(displayContent);
-                }
-            }
-
-            for (DisplayContent displayContent : displayList) {
-                assignLayersLocked(displayContent.getWindowList());
-                displayContent.layoutNeeded = true;
-            }
-        }
-
-        // Remove all deferred displays stacks, tasks, and activities.
-        for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
-            mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
-        }
-
-        if (updateInputWindowsNeeded) {
-            mInputMonitor.updateInputWindowsLw(false /*force*/);
-        }
-        setFocusTaskRegion();
-
-        // Check to see if we are now in a state where the screen should
-        // be enabled, because the window obscured flags have changed.
-        enableScreenIfNeededLocked();
-
-        scheduleAnimationLocked();
-
-        if (DEBUG_WINDOW_TRACE) {
-            Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
-                    + mAnimator.mAnimating);
-        }
-    }
-
-    private int toBrightnessOverride(float value) {
-        return (int)(value * PowerManager.BRIGHTNESS_ON);
-    }
-
     void checkDrawnWindowsLocked() {
         if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
             return;
@@ -9829,7 +8434,7 @@
         }
     }
 
-    private boolean needsLayout() {
+    boolean needsLayout() {
         final int numDisplays = mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
@@ -9840,41 +8445,6 @@
         return false;
     }
 
-    boolean copyAnimToLayoutParamsLocked() {
-        boolean doRequest = false;
-
-        final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
-        if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
-            mInnerFields.mUpdateRotation = true;
-            doRequest = true;
-        }
-        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
-            mInnerFields.mWallpaperMayChange = true;
-            doRequest = true;
-        }
-        if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
-            mInnerFields.mWallpaperForceHidingChanged = true;
-            doRequest = true;
-        }
-        if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
-            mInnerFields.mOrientationChangeComplete = false;
-        } else {
-            mInnerFields.mOrientationChangeComplete = true;
-            mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
-            if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
-                doRequest = true;
-            }
-        }
-        if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
-            mTurnOnScreen = true;
-        }
-        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
-            mInnerFields.mWallpaperActionPending = true;
-        }
-
-        return doRequest;
-    }
-
     /** If a window that has an animation specifying a colored background and the current wallpaper
      * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
      * suddenly disappear. */
@@ -9998,7 +8568,7 @@
         return leakedSurface || killedApps;
     }
 
-    private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
+    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
         WindowState newFocus = computeFocusedWindowLocked();
         if (mCurrentFocus != newFocus) {
             Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
@@ -10027,7 +8597,8 @@
             if (imWindowChanged && oldFocus != mInputMethodWindow) {
                 // Focus of the input method window changed. Perform layout if needed.
                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
-                    performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
+                    mWindowPlacerLocked.performLayoutLockedInner(displayContent, true /*initial*/,
+                            updateInputWindows);
                     focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
                 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
                     // Client will do the layout, but we need to assign layers
@@ -10040,7 +8611,8 @@
                 // The change in focus caused us to need to do a layout.  Okay.
                 displayContent.layoutNeeded = true;
                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
-                    performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
+                    mWindowPlacerLocked.performLayoutLockedInner(displayContent, true /*initial*/,
+                            updateInputWindows);
                 }
             }
 
@@ -10068,7 +8640,7 @@
         return null;
     }
 
-    private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
+    WindowState findFocusedWindowLocked(DisplayContent displayContent) {
         final WindowList windows = displayContent.getWindowList();
         for (int i = windows.size() - 1; i >= 0; i--) {
             final WindowState win = windows.get(i);
@@ -10192,7 +8764,7 @@
         }
     }
 
-    private void stopFreezingDisplayLocked() {
+    void stopFreezingDisplayLocked() {
         if (!mDisplayFrozen) {
             return;
         }
@@ -10399,7 +8971,7 @@
         synchronized (mWindowMap) {
             int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
             updateStatusBarVisibilityLocked(visibility);
-            performLayoutAndPlaceSurfacesLocked();
+            mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
@@ -11013,13 +9585,6 @@
         synchronized (mWindowMap) { }
     }
 
-    void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
-        if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
-            Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
-                    Integer.toHexString(pendingLayoutChanges));
-        }
-    }
-
     private DisplayContent newDisplayContentLocked(final Display display) {
         DisplayContent displayContent = new DisplayContent(display, this);
         final int displayId = display.getDisplayId();
@@ -11158,6 +9723,17 @@
         return mWindowMap;
     }
 
+    public void setReplacingWindow(IBinder token) {
+        synchronized (mWindowMap) {
+            AppWindowToken appWindowToken = findAppWindowToken(token);
+            if (appWindowToken == null) {
+                Slog.w(TAG, "Attempted to set replacing window on non-existing app token " + token);
+                return;
+            }
+            appWindowToken.mReplacingWindow = true;
+        }
+    }
+
     private final class LocalService extends WindowManagerInternal {
         @Override
         public void requestTraversalFromDisplayManager() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 761e5eb..49d260e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
@@ -1255,6 +1256,33 @@
         mInputWindowHandle.inputChannel = null;
     }
 
+    void handleFlagDimBehind() {
+        if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 && isDisplayedLw() && !mExiting) {
+            final Task task = getTask();
+            if (task == null) {
+                return;
+            }
+            task.setContinueDimming();
+            if (!task.isDimming(mWinAnimator)) {
+                if (WindowManagerService.localLOGV) Slog.v(TAG, "Win " + this + " start dimming.");
+                task.startDimmingIfNeeded(mWinAnimator);
+            }
+        }
+    }
+
+    void maybeRemoveReplacedWindow() {
+        AppWindowToken token = mAppToken;
+        if (token != null && token.mReplacingWindow) {
+            token.mReplacingWindow = false;
+            for (int i = token.allAppWindows.size() - 1; i >= 0; i--) {
+                WindowState win = token.allAppWindows.get(i);
+                if (win.mExiting) {
+                    mService.removeWindowInnerLocked(win);
+                }
+            }
+        }
+    }
+
     private class DeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 109e627..efad8bf 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -27,8 +27,8 @@
 import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerService.localLOGV;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
-import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
 
 import android.content.Context;
 import android.graphics.Matrix;
@@ -424,8 +424,9 @@
         finishExit();
         final int displayId = mWin.getDisplayId();
         mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
-                "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
+        if (WindowManagerService.DEBUG_LAYOUT_REPEATS)
+            mService.mWindowPlacerLocked.debugLayoutRepeats(
+                    "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
 
         if (mWin.mAppToken != null) {
             mWin.mAppToken.updateReportedVisibilityLocked();
@@ -1184,7 +1185,7 @@
                     + " screen=" + (screenAnimation ?
                             screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
             return;
-        } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) {
+        } else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
             return;
         }
 
@@ -1764,6 +1765,8 @@
                 mWin.mAppToken.updateReportedVisibilityLocked();
             }
 
+            mWin.maybeRemoveReplacedWindow();
+
             return true;
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
new file mode 100644
index 0000000..ce07a9d
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -0,0 +1,1523 @@
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG;
+import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
+import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerService.DEBUG_TOKEN_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerService.H.*;
+import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
+import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
+import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Positions windows and their surfaces.
+ *
+ * It sets positions of windows by calculating their frames and then applies this by positioning
+ * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
+ */
+class WindowSurfacePlacer {
+    private final WindowManagerService mService;
+    private final WallpaperController mWallpaperControllerLocked;
+
+    private boolean mInLayout = false;
+
+    /** Only do a maximum of 6 repeated layouts. After that quit */
+    private int mLayoutRepeatCount;
+
+    static final int SET_UPDATE_ROTATION                = 1 << 0;
+    static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
+    static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
+    static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 3;
+    static final int SET_TURN_ON_SCREEN                 = 1 << 4;
+    static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 5;
+
+    boolean mWallpaperMayChange = false;
+    boolean mOrientationChangeComplete = true;
+    boolean mWallpaperActionPending = false;
+
+    private boolean mWallpaperForceHidingChanged = false;
+    private Object mLastWindowFreezeSource = null;
+    private Session mHoldScreen = null;
+    private boolean mObscured = false;
+    private boolean mSyswin = false;
+    private float mScreenBrightness = -1;
+    private float mButtonBrightness = -1;
+    private long mUserActivityTimeout = -1;
+    private boolean mUpdateRotation = false;
+    private final Rect mTmpStartRect = new Rect();
+
+    // Set to true when the display contains content to show the user.
+    // When false, the display manager may choose to mirror or blank the display.
+    private boolean mDisplayHasContent = false;
+
+    // Only set while traversing the default display based on its content.
+    // Affects the behavior of mirroring on secondary displays.
+    private boolean mObscureApplicationContentOnSecondaryDisplays = false;
+
+    private float mPreferredRefreshRate = 0;
+
+    private int mPreferredModeId = 0;
+
+    public WindowSurfacePlacer(WindowManagerService service) {
+        mService = service;
+        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
+    }
+
+    final void performSurfacePlacement() {
+        int loopCount = 6;
+        do {
+            mService.mTraversalScheduled = false;
+            performSurfacePlacementLoop();
+            mService.mH.removeMessages(DO_TRAVERSAL);
+            loopCount--;
+        } while (mService.mTraversalScheduled && loopCount > 0);
+        mWallpaperActionPending = false;
+    }
+
+    private void performSurfacePlacementLoop() {
+        if (mInLayout) {
+            if (DEBUG) {
+                throw new RuntimeException("Recursive call!");
+            }
+            Slog.w(TAG,
+                    "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+                    + Debug.getCallers(3));
+            return;
+        }
+
+        if (mService.mWaitingForConfig) {
+            // Our configuration has changed (most likely rotation), but we
+            // don't yet have the complete configuration to report to
+            // applications.  Don't do any window layout until we have it.
+            return;
+        }
+
+        if (!mService.mDisplayReady) {
+            // Not yet initialized, nothing to do.
+            return;
+        }
+
+        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
+        mInLayout = true;
+
+        boolean recoveringMemory = false;
+        if (!mService.mForceRemoves.isEmpty()) {
+            recoveringMemory = true;
+            // Wait a little bit for things to settle down, and off we go.
+            while (!mService.mForceRemoves.isEmpty()) {
+                WindowState ws = mService.mForceRemoves.remove(0);
+                Slog.i(TAG, "Force removing: " + ws);
+                mService.removeWindowInnerLocked(ws);
+            }
+            Slog.w(TAG,
+                    "Due to memory failure, waiting a bit for next layout");
+            Object tmp = new Object();
+            synchronized (tmp) {
+                try {
+                    tmp.wait(250);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        try {
+            performSurfacePlacementInner(recoveringMemory);
+
+            mInLayout = false;
+
+            if (mService.needsLayout()) {
+                if (++mLayoutRepeatCount < 6) {
+                    mService.requestTraversalLocked();
+                } else {
+                    Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
+                    mLayoutRepeatCount = 0;
+                }
+            } else {
+                mLayoutRepeatCount = 0;
+            }
+
+            if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
+                mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
+                mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
+            }
+        } catch (RuntimeException e) {
+            mInLayout = false;
+            Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
+        }
+
+        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+    }
+
+    void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
+        if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
+            Slog.v(TAG, "Layouts looping: " + msg +
+                    ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
+        }
+    }
+
+    // "Something has changed!  Let's make it correct now."
+    private void performSurfacePlacementInner(boolean recoveringMemory) {
+        if (DEBUG_WINDOW_TRACE) {
+            Slog.v(TAG,
+                    "performSurfacePlacementInner: entry. Called by "
+                    + Debug.getCallers(3));
+        }
+
+        int i;
+        boolean updateInputWindowsNeeded = false;
+
+        if (mService.mFocusMayChange) {
+            mService.mFocusMayChange = false;
+            updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
+                    UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
+        }
+
+        // Initialize state of exiting tokens.
+        final int numDisplays = mService.mDisplayContents.size();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+            for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
+                displayContent.mExitingTokens.get(i).hasVisible = false;
+            }
+        }
+
+        for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
+            // Initialize state of exiting applications.
+            final AppTokenList exitingAppTokens =
+                    mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
+            for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                exitingAppTokens.get(tokenNdx).hasVisible = false;
+            }
+        }
+
+        mHoldScreen = null;
+        mScreenBrightness = -1;
+        mButtonBrightness = -1;
+        mUserActivityTimeout = -1;
+        mObscureApplicationContentOnSecondaryDisplays = false;
+
+        mService.mTransactionSequence++;
+
+        final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
+        final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
+        final int defaultDw = defaultInfo.logicalWidth;
+        final int defaultDh = defaultInfo.logicalHeight;
+
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+        SurfaceControl.openTransaction();
+        try {
+
+            if (mService.mWatermark != null) {
+                mService.mWatermark.positionSurface(defaultDw, defaultDh);
+            }
+            if (mService.mStrictModeFlash != null) {
+                mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
+            }
+            if (mService.mCircularDisplayMask != null) {
+                mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
+                        mService.mRotation);
+            }
+            if (mService.mEmulatorDisplayOverlay != null) {
+                mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
+                        mService.mRotation);
+            }
+
+            boolean focusDisplayed = false;
+
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+                final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+                boolean updateAllDrawn = false;
+                WindowList windows = displayContent.getWindowList();
+                DisplayInfo displayInfo = displayContent.getDisplayInfo();
+                final int displayId = displayContent.getDisplayId();
+                final int dw = displayInfo.logicalWidth;
+                final int dh = displayInfo.logicalHeight;
+                final int innerDw = displayInfo.appWidth;
+                final int innerDh = displayInfo.appHeight;
+                final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+
+                // Reset for each display.
+                mDisplayHasContent = false;
+                mPreferredRefreshRate = 0;
+                mPreferredModeId = 0;
+
+                int repeats = 0;
+                do {
+                    repeats++;
+                    if (repeats > 6) {
+                        Slog.w(TAG, "Animation repeat aborted after too many iterations");
+                        displayContent.layoutNeeded = false;
+                        break;
+                    }
+
+                    if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
+                            "On entry to LockedInner", displayContent.pendingLayoutChanges);
+
+                    if ((displayContent.pendingLayoutChanges &
+                            FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
+                            mWallpaperControllerLocked.adjustWallpaperWindows()) {
+                        mService.assignLayersLocked(windows);
+                        displayContent.layoutNeeded = true;
+                    }
+
+                    if (isDefaultDisplay && (displayContent.pendingLayoutChanges
+                            & FINISH_LAYOUT_REDO_CONFIG) != 0) {
+                        if (DEBUG_LAYOUT) Slog.v(TAG,
+                                "Computing new config from layout");
+                        if (mService.updateOrientationFromAppTokensLocked(true)) {
+                            displayContent.layoutNeeded = true;
+                            mService.mH.sendEmptyMessage(
+                                    SEND_NEW_CONFIGURATION);
+                        }
+                    }
+
+                    if ((displayContent.pendingLayoutChanges
+                            & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+                        displayContent.layoutNeeded = true;
+                    }
+
+                    // FIRST LOOP: Perform a layout, if needed.
+                    if (repeats < LAYOUT_REPEAT_THRESHOLD) {
+                        performLayoutLockedInner(displayContent, repeats == 1,
+                                false /*updateInputWindows*/);
+                    } else {
+                        Slog.w(TAG, "Layout repeat skipped after too many iterations");
+                    }
+
+                    // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
+                    // it is animating.
+                    displayContent.pendingLayoutChanges = 0;
+
+                    if (isDefaultDisplay) {
+                        mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
+                        for (i = windows.size() - 1; i >= 0; i--) {
+                            WindowState w = windows.get(i);
+                            if (w.mHasSurface) {
+                                mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
+                                        w.mAttachedWindow);
+                            }
+                        }
+                        displayContent.pendingLayoutChanges |=
+                                mService.mPolicy.finishPostLayoutPolicyLw();
+                        if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
+                                "after finishPostLayoutPolicyLw",
+                                displayContent.pendingLayoutChanges);
+                    }
+                } while (displayContent.pendingLayoutChanges != 0);
+
+                mObscured = false;
+                mSyswin = false;
+                displayContent.resetDimming();
+
+                // Only used if default window
+                final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
+
+                final int N = windows.size();
+                for (i=N-1; i>=0; i--) {
+                    WindowState w = windows.get(i);
+                    final Task task = w.getTask();
+                    if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
+                        continue;
+                    }
+
+                    final boolean obscuredChanged = w.mObscured != mObscured;
+
+                    // Update effect.
+                    w.mObscured = mObscured;
+                    if (!mObscured) {
+                        handleNotObscuredLocked(w, innerDw, innerDh);
+                    }
+
+                    if (task != null && !task.getContinueDimming()) {
+                        w.handleFlagDimBehind();
+                    }
+
+                    if (isDefaultDisplay && obscuredChanged
+                            && mWallpaperControllerLocked.isWallpaperTarget(w)
+                            && w.isVisibleLw()) {
+                        // This is the wallpaper target and its obscured state
+                        // changed... make sure the current wallaper's visibility
+                        // has been updated accordingly.
+                        mWallpaperControllerLocked.updateWallpaperVisibility();
+                    }
+
+                    final WindowStateAnimator winAnimator = w.mWinAnimator;
+
+                    // If the window has moved due to its containing content frame changing, then
+                    // notify the listeners and optionally animate it.
+                    if (w.hasMoved()) {
+                        // Frame has moved, containing content frame has also moved, and we're not
+                        // currently animating... let's do something.
+                        final int left = w.mFrame.left;
+                        final int top = w.mFrame.top;
+                        if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
+                            Animation a = AnimationUtils.loadAnimation(mService.mContext,
+                                    com.android.internal.R.anim.window_move_from_decor);
+                            winAnimator.setAnimation(a);
+                            winAnimator.mAnimDw = w.mLastFrame.left - left;
+                            winAnimator.mAnimDh = w.mLastFrame.top - top;
+                            winAnimator.mAnimateMove = true;
+                            winAnimator.mAnimatingMove = true;
+                        }
+
+                        //TODO (multidisplay): Accessibility supported only for the default display.
+                        if (mService.mAccessibilityController != null
+                                && displayId == Display.DEFAULT_DISPLAY) {
+                            mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+                        }
+
+                        try {
+                            w.mClient.moved(left, top);
+                        } catch (RemoteException e) {
+                        }
+                    }
+
+                    //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+                    w.mContentChanged = false;
+
+                    // Moved from updateWindowsAndWallpaperLocked().
+                    if (w.mHasSurface) {
+                        // Take care of the window being ready to display.
+                        final boolean committed =
+                                winAnimator.commitFinishDrawingLocked();
+                        if (isDefaultDisplay && committed) {
+                            if (w.mAttrs.type == TYPE_DREAM) {
+                                // HACK: When a dream is shown, it may at that
+                                // point hide the lock screen.  So we need to
+                                // redo the layout to let the phone window manager
+                                // make this happen.
+                                displayContent.pendingLayoutChanges |=
+                                        FINISH_LAYOUT_REDO_LAYOUT;
+                                if (DEBUG_LAYOUT_REPEATS) {
+                                    debugLayoutRepeats(
+                                            "dream and commitFinishDrawingLocked true",
+                                            displayContent.pendingLayoutChanges);
+                                }
+                            }
+                            if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+                                if (DEBUG_WALLPAPER_LIGHT)
+                                    Slog.v(TAG,
+                                            "First draw done in potential wallpaper target " + w);
+                                mWallpaperMayChange = true;
+                                displayContent.pendingLayoutChanges |=
+                                        FINISH_LAYOUT_REDO_WALLPAPER;
+                                if (DEBUG_LAYOUT_REPEATS) {
+                                    debugLayoutRepeats(
+                                            "wallpaper and commitFinishDrawingLocked true",
+                                            displayContent.pendingLayoutChanges);
+                                }
+                            }
+                        }
+
+                        winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
+                    }
+
+                    final AppWindowToken atoken = w.mAppToken;
+                    if (DEBUG_STARTING_WINDOW && atoken != null
+                            && w == atoken.startingWindow) {
+                        Slog.d(TAG, "updateWindows: starting " + w
+                                + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+                                + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
+                    }
+                    if (atoken != null
+                            && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
+                        if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
+                            atoken.lastTransactionSequence = mService.mTransactionSequence;
+                            atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+                            atoken.startingDisplayed = false;
+                        }
+                        if ((w.isOnScreenIgnoringKeyguard()
+                                || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
+                                && !w.mExiting && !w.mDestroying) {
+                            if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
+                                Slog.v(TAG, "Eval win " + w + ": isDrawn="
+                                        + w.isDrawnLw()
+                                        + ", isAnimating=" + winAnimator.isAnimating());
+                                if (!w.isDrawnLw()) {
+                                    Slog.v(TAG, "Not displayed: s="
+                                            + winAnimator.mSurfaceControl
+                                            + " pv=" + w.mPolicyVisibility
+                                            + " mDrawState=" + winAnimator.drawStateToString()
+                                            + " ah=" + w.mAttachedHidden
+                                            + " th=" + atoken.hiddenRequested
+                                            + " a=" + winAnimator.mAnimating);
+                                }
+                            }
+                            if (w != atoken.startingWindow) {
+                                if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
+                                    atoken.numInterestingWindows++;
+                                    if (w.isDrawnLw()) {
+                                        atoken.numDrawnWindows++;
+                                        if (DEBUG_VISIBILITY
+                                                || DEBUG_ORIENTATION)
+                                            Slog.v(TAG,
+                                                "tokenMayBeDrawn: " + atoken
+                                                + " freezingScreen="
+                                                + atoken.mAppAnimator.freezingScreen
+                                                + " mAppFreezing=" + w.mAppFreezing);
+                                        updateAllDrawn = true;
+                                    }
+                                }
+                            } else if (w.isDrawnLw()) {
+                                atoken.startingDisplayed = true;
+                            }
+                        }
+                    }
+
+                    if (isDefaultDisplay && someoneLosingFocus && (w == mService.mCurrentFocus)
+                            && w.isDisplayedLw()) {
+                        focusDisplayed = true;
+                    }
+
+                    mService.updateResizingWindows(w);
+                }
+
+                mService.mDisplayManagerInternal.setDisplayProperties(displayId,
+                        mDisplayHasContent,
+                        mPreferredRefreshRate,
+                        mPreferredModeId,
+                        true /* inTraversal, must call performTraversalInTrans... below */);
+
+                mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
+
+                if (updateAllDrawn) {
+                    updateAllDrawnLocked(displayContent);
+                }
+            }
+
+            if (focusDisplayed) {
+                mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
+            }
+
+            // Give the display manager a chance to adjust properties
+            // like display rotation if it needs to.
+            mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
+
+        } catch (RuntimeException e) {
+            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
+        }
+
+        final WindowList defaultWindows = defaultDisplay.getWindowList();
+
+        // If we are ready to perform an app transition, check through
+        // all of the app tokens to be shown and see if they are ready
+        // to go.
+        if (mService.mAppTransition.isReady()) {
+            defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
+            if (DEBUG_LAYOUT_REPEATS)
+                debugLayoutRepeats("after handleAppTransitionReadyLocked",
+                        defaultDisplay.pendingLayoutChanges);
+        }
+
+        if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
+            // We have finished the animation of an app transition.  To do
+            // this, we have delayed a lot of operations like showing and
+            // hiding apps, moving apps in Z-order, etc.  The app token list
+            // reflects the correct Z-order, but the window list may now
+            // be out of sync with it.  So here we will just rebuild the
+            // entire app window list.  Fun!
+            defaultDisplay.pendingLayoutChanges |=
+                    mService.handleAnimatingStoppedAndTransitionLocked();
+            if (DEBUG_LAYOUT_REPEATS)
+                debugLayoutRepeats("after handleAnimStopAndXitionLock",
+                        defaultDisplay.pendingLayoutChanges);
+        }
+
+        if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
+                && !mService.mAppTransition.isReady()) {
+            // At this point, there was a window with a wallpaper that
+            // was force hiding other windows behind it, but now it
+            // is going away.  This may be simple -- just animate
+            // away the wallpaper and its window -- or it may be
+            // hard -- the wallpaper now needs to be shown behind
+            // something that was hidden.
+            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+            if (DEBUG_LAYOUT_REPEATS)
+                debugLayoutRepeats("after animateAwayWallpaperLocked",
+                        defaultDisplay.pendingLayoutChanges);
+        }
+        mWallpaperForceHidingChanged = false;
+
+        if (mWallpaperMayChange) {
+            if (DEBUG_WALLPAPER_LIGHT)
+                Slog.v(TAG, "Wallpaper may change!  Adjusting");
+            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
+                    defaultDisplay.pendingLayoutChanges);
+        }
+
+        if (mService.mFocusMayChange) {
+            mService.mFocusMayChange = false;
+            if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+                    false /*updateInputWindows*/)) {
+                updateInputWindowsNeeded = true;
+                defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
+            }
+        }
+
+        if (mService.needsLayout()) {
+            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
+                    defaultDisplay.pendingLayoutChanges);
+        }
+
+        for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
+            WindowState win = mService.mResizingWindows.get(i);
+            if (win.mAppFreezing) {
+                // Don't remove this window until rotation has completed.
+                continue;
+            }
+            win.reportResized();
+            mService.mResizingWindows.remove(i);
+        }
+
+        if (DEBUG_ORIENTATION && mService.mDisplayFrozen)
+            Slog.v(TAG,
+                "With display frozen, orientationChangeComplete="
+                + mOrientationChangeComplete);
+        if (mOrientationChangeComplete) {
+            if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+                mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
+                mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
+                mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
+            }
+            mService.stopFreezingDisplayLocked();
+        }
+
+        // Destroy the surface of any windows that are no longer visible.
+        boolean wallpaperDestroyed = false;
+        i = mService.mDestroySurface.size();
+        if (i > 0) {
+            do {
+                i--;
+                WindowState win = mService.mDestroySurface.get(i);
+                win.mDestroying = false;
+                if (mService.mInputMethodWindow == win) {
+                    mService.mInputMethodWindow = null;
+                }
+                if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
+                    wallpaperDestroyed = true;
+                }
+                win.mWinAnimator.destroySurfaceLocked();
+            } while (i > 0);
+            mService.mDestroySurface.clear();
+        }
+
+        // Time to remove any exiting tokens?
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+            ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
+            for (i = exitingTokens.size() - 1; i >= 0; i--) {
+                WindowToken token = exitingTokens.get(i);
+                if (!token.hasVisible) {
+                    exitingTokens.remove(i);
+                    if (token.windowType == TYPE_WALLPAPER) {
+                        mWallpaperControllerLocked.removeWallpaperToken(token);
+                    }
+                }
+            }
+        }
+
+        // Time to remove any exiting applications?
+        for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
+            // Initialize state of exiting applications.
+            final AppTokenList exitingAppTokens =
+                    mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
+            for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
+                AppWindowToken token = exitingAppTokens.get(i);
+                if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
+                        (!token.mIsExiting || token.allAppWindows.isEmpty())) {
+                    // Make sure there is no animation running on this token,
+                    // so any windows associated with it will be removed as
+                    // soon as their animations are complete
+                    token.mAppAnimator.clearAnimation();
+                    token.mAppAnimator.animating = false;
+                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT)
+                        Slog.v(TAG,
+                                "performLayout: App token exiting now removed" + token);
+                    token.removeAppFromTaskLocked();
+                }
+            }
+        }
+
+        if (wallpaperDestroyed) {
+            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+            defaultDisplay.layoutNeeded = true;
+        }
+
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+            if (displayContent.pendingLayoutChanges != 0) {
+                displayContent.layoutNeeded = true;
+            }
+        }
+
+        // Finally update all input windows now that the window changes have stabilized.
+        mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+
+        mService.setHoldScreenLocked(mHoldScreen);
+        if (!mService.mDisplayFrozen) {
+            if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
+                mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
+            } else {
+                mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
+                        toBrightnessOverride(mScreenBrightness));
+            }
+            if (mButtonBrightness < 0
+                    || mButtonBrightness > 1.0f) {
+                mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
+            } else {
+                mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
+                        toBrightnessOverride(mButtonBrightness));
+            }
+            mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
+                    mUserActivityTimeout);
+        }
+
+        if (mService.mTurnOnScreen) {
+            if (mService.mAllowTheaterModeWakeFromLayout
+                    || Settings.Global.getInt(mService.mContext.getContentResolver(),
+                        Settings.Global.THEATER_MODE_ON, 0) == 0) {
+                if (DEBUG_VISIBILITY || DEBUG_POWER) {
+                    Slog.v(TAG, "Turning screen on after layout!");
+                }
+                mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
+                        "android.server.wm:TURN_ON");
+            }
+            mService.mTurnOnScreen = false;
+        }
+
+        if (mUpdateRotation) {
+            if (DEBUG_ORIENTATION) Slog.d(TAG,
+                    "Performing post-rotate rotation");
+            if (mService.updateRotationUncheckedLocked(false)) {
+                mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+            } else {
+                mUpdateRotation = false;
+            }
+        }
+
+        if (mService.mWaitingForDrawnCallback != null ||
+                (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
+                        !mUpdateRotation)) {
+            mService.checkDrawnWindowsLocked();
+        }
+
+        final int N = mService.mPendingRemove.size();
+        if (N > 0) {
+            if (mService.mPendingRemoveTmp.length < N) {
+                mService.mPendingRemoveTmp = new WindowState[N+10];
+            }
+            mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
+            mService.mPendingRemove.clear();
+            DisplayContentList displayList = new DisplayContentList();
+            for (i = 0; i < N; i++) {
+                WindowState w = mService.mPendingRemoveTmp[i];
+                mService.removeWindowInnerLocked(w);
+                final DisplayContent displayContent = w.getDisplayContent();
+                if (displayContent != null && !displayList.contains(displayContent)) {
+                    displayList.add(displayContent);
+                }
+            }
+
+            for (DisplayContent displayContent : displayList) {
+                mService.assignLayersLocked(displayContent.getWindowList());
+                displayContent.layoutNeeded = true;
+            }
+        }
+
+        // Remove all deferred displays stacks, tasks, and activities.
+        for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+            mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
+        }
+
+        if (updateInputWindowsNeeded) {
+            mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+        }
+        mService.setFocusTaskRegion();
+
+        // Check to see if we are now in a state where the screen should
+        // be enabled, because the window obscured flags have changed.
+        mService.enableScreenIfNeededLocked();
+
+        mService.scheduleAnimationLocked();
+
+        if (DEBUG_WINDOW_TRACE) {
+            Slog.e(TAG,
+                    "performSurfacePlacementInner exit: animating="
+                            + mService.mAnimator.mAnimating);
+        }
+    }
+
+    boolean isInLayout() {
+        return mInLayout;
+    }
+
+    final void performLayoutLockedInner(final DisplayContent displayContent,
+            boolean initial, boolean updateInputWindows) {
+        if (!displayContent.layoutNeeded) {
+            return;
+        }
+        displayContent.layoutNeeded = false;
+        WindowList windows = displayContent.getWindowList();
+        boolean isDefaultDisplay = displayContent.isDefaultDisplay;
+
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
+
+        if (mService.mInputConsumer != null) {
+            mService.mInputConsumer.layout(dw, dh);
+        }
+
+        final int N = windows.size();
+        int i;
+
+        if (DEBUG_LAYOUT) {
+            Slog.v(TAG, "-------------------------------------");
+            Slog.v(TAG, "performLayout: needed="
+                    + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
+        }
+
+        mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation);
+        if (isDefaultDisplay) {
+            // Not needed on non-default displays.
+            mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
+            mService.mScreenRect.set(0, 0, dw, dh);
+        }
+
+        mService.mPolicy.getContentRectLw(mService.mTmpContentRect);
+        displayContent.resize(mService.mTmpContentRect);
+
+        int seq = mService.mLayoutSeq+1;
+        if (seq < 0) seq = 0;
+        mService.mLayoutSeq = seq;
+
+        boolean behindDream = false;
+
+        // First perform layout of any root windows (not attached
+        // to another window).
+        int topAttached = -1;
+        for (i = N-1; i >= 0; i--) {
+            final WindowState win = windows.get(i);
+
+            // Don't do layout of a window if it is not visible, or
+            // soon won't be visible, to avoid wasting time and funky
+            // changes while a window is animating away.
+            final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
+                    || win.isGoneForLayoutLw();
+
+            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
+                Slog.v(TAG, "1ST PASS " + win
+                        + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
+                        + " mLayoutAttached=" + win.mLayoutAttached
+                        + " screen changed=" + win.isConfigChanged());
+                final AppWindowToken atoken = win.mAppToken;
+                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
+                        + win.mViewVisibility + " mRelayoutCalled="
+                        + win.mRelayoutCalled + " hidden="
+                        + win.mRootToken.hidden + " hiddenRequested="
+                        + (atoken != null && atoken.hiddenRequested)
+                        + " mAttachedHidden=" + win.mAttachedHidden);
+                else Slog.v(TAG, "  VIS: mViewVisibility="
+                        + win.mViewVisibility + " mRelayoutCalled="
+                        + win.mRelayoutCalled + " hidden="
+                        + win.mRootToken.hidden + " hiddenRequested="
+                        + (atoken != null && atoken.hiddenRequested)
+                        + " mAttachedHidden=" + win.mAttachedHidden);
+            }
+
+            // If this view is GONE, then skip it -- keep the current
+            // frame, and let the caller know so they can ignore it
+            // if they want.  (We do the normal layout for INVISIBLE
+            // windows, since that means "perform layout as normal,
+            // just don't display").
+            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
+                    || ((win.isConfigChanged() || win.setInsetsChanged()) &&
+                            ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
+                            (win.mHasSurface && win.mAppToken != null &&
+                            win.mAppToken.layoutConfigChanges)))) {
+                if (!win.mLayoutAttached) {
+                    if (initial) {
+                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+                        win.mContentChanged = false;
+                    }
+                    if (win.mAttrs.type == TYPE_DREAM) {
+                        // Don't layout windows behind a dream, so that if it
+                        // does stuff like hide the status bar we won't get a
+                        // bad transition when it goes away.
+                        behindDream = true;
+                    }
+                    win.mLayoutNeeded = false;
+                    win.prelayout();
+                    mService.mPolicy.layoutWindowLw(win, null);
+                    win.mLayoutSeq = seq;
+                    if (DEBUG_LAYOUT) Slog.v(TAG,
+                            "  LAYOUT: mFrame="
+                            + win.mFrame + " mContainingFrame="
+                            + win.mContainingFrame + " mDisplayFrame="
+                            + win.mDisplayFrame);
+                } else {
+                    if (topAttached < 0) topAttached = i;
+                }
+            }
+        }
+
+        boolean attachedBehindDream = false;
+
+        // Now perform layout of attached windows, which usually
+        // depend on the position of the window they are attached to.
+        // XXX does not deal with windows that are attached to windows
+        // that are themselves attached.
+        for (i = topAttached; i >= 0; i--) {
+            final WindowState win = windows.get(i);
+
+            if (win.mLayoutAttached) {
+                if (DEBUG_LAYOUT) Slog.v(TAG,
+                        "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
+                        + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
+                // If this view is GONE, then skip it -- keep the current
+                // frame, and let the caller know so they can ignore it
+                // if they want.  (We do the normal layout for INVISIBLE
+                // windows, since that means "perform layout as normal,
+                // just don't display").
+                if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
+                    continue;
+                }
+                if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
+                        || !win.mHaveFrame || win.mLayoutNeeded) {
+                    if (initial) {
+                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+                        win.mContentChanged = false;
+                    }
+                    win.mLayoutNeeded = false;
+                    win.prelayout();
+                    mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
+                    win.mLayoutSeq = seq;
+                    if (DEBUG_LAYOUT) Slog.v(TAG,
+                            "  LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
+                            + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
+                }
+            } else if (win.mAttrs.type == TYPE_DREAM) {
+                // Don't layout windows behind a dream, so that if it
+                // does stuff like hide the status bar we won't get a
+                // bad transition when it goes away.
+                attachedBehindDream = behindDream;
+            }
+        }
+
+        // Window frames may have changed.  Tell the input dispatcher about it.
+        mService.mInputMonitor.setUpdateInputWindowsNeededLw();
+        if (updateInputWindows) {
+            mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+        }
+
+        mService.mPolicy.finishLayoutLw();
+    }
+
+    /**
+     * @param windows List of windows on default display.
+     * @return bitmap indicating if another pass through layout must be made.
+     */
+    private int handleAppTransitionReadyLocked(WindowList windows) {
+        int appsCount = mService.mOpeningApps.size();
+        if (!transitionGoodToGo(appsCount)) {
+            return 0;
+        }
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
+        int transit = mService.mAppTransition.getAppTransition();
+        if (mService.mSkipAppTransitionAnimation) {
+            transit = AppTransition.TRANSIT_UNSET;
+        }
+        mService.mSkipAppTransitionAnimation = false;
+        mService.mNoAnimationNotifyOnTransitionFinished.clear();
+
+        mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
+
+        mService.rebuildAppWindowListLocked();
+
+        mWallpaperMayChange = false;
+
+        // The top-most window will supply the layout params,
+        // and we will determine it below.
+        WindowManager.LayoutParams animLp = null;
+        int bestAnimLayer = -1;
+        boolean fullscreenAnim = false;
+        boolean voiceInteraction = false;
+
+        final WindowState lowerWallpaperTarget =
+                mWallpaperControllerLocked.getLowerWallpaperTarget();
+        final WindowState upperWallpaperTarget =
+                mWallpaperControllerLocked.getUpperWallpaperTarget();
+
+        boolean openingAppHasWallpaper = false;
+        boolean closingAppHasWallpaper = false;
+        final AppWindowToken lowerWallpaperAppToken;
+        final AppWindowToken upperWallpaperAppToken;
+        if (lowerWallpaperTarget == null) {
+            lowerWallpaperAppToken = upperWallpaperAppToken = null;
+        } else {
+            lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
+            upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
+        }
+
+        int i;
+        // Do a first pass through the tokens for two
+        // things:
+        // (1) Determine if both the closing and opening
+        // app token sets are wallpaper targets, in which
+        // case special animations are needed
+        // (since the wallpaper needs to stay static
+        // behind them).
+        // (2) Find the layout params of the top-most
+        // application window in the tokens, which is
+        // what will control the animation theme.
+        final int closingAppsCount = mService.mClosingApps.size();
+        appsCount = closingAppsCount + mService.mOpeningApps.size();
+        for (i = 0; i < appsCount; i++) {
+            final AppWindowToken wtoken;
+            if (i < closingAppsCount) {
+                wtoken = mService.mClosingApps.valueAt(i);
+                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+                    closingAppHasWallpaper = true;
+                }
+            } else {
+                wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
+                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+                    openingAppHasWallpaper = true;
+                }
+            }
+
+            voiceInteraction |= wtoken.voiceInteraction;
+
+            if (wtoken.appFullscreen) {
+                WindowState ws = wtoken.findMainWindow();
+                if (ws != null) {
+                    animLp = ws.mAttrs;
+                    bestAnimLayer = ws.mLayer;
+                    fullscreenAnim = true;
+                }
+            } else if (!fullscreenAnim) {
+                WindowState ws = wtoken.findMainWindow();
+                if (ws != null) {
+                    if (ws.mLayer > bestAnimLayer) {
+                        animLp = ws.mAttrs;
+                        bestAnimLayer = ws.mLayer;
+                    }
+                }
+            }
+        }
+
+        transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
+                closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
+
+        // If all closing windows are obscured, then there is
+        // no need to do an animation.  This is the case, for
+        // example, when this transition is being done behind
+        // the lock screen.
+        if (!mService.mPolicy.allowAppAnimationsLw()) {
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "Animations disallowed by keyguard or dream.");
+            animLp = null;
+        }
+
+        processApplicationsAnimatingInPlace(transit);
+
+        AppWindowToken topClosingApp = null;
+        int topClosingLayer = 0;
+        appsCount = mService.mClosingApps.size();
+        for (i = 0; i < appsCount; i++) {
+            AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
+            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "Now closing app " + wtoken);
+            appAnimator.clearThumbnail();
+            appAnimator.animation = null;
+            wtoken.inPendingTransaction = false;
+            mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
+                    voiceInteraction);
+            wtoken.updateReportedVisibilityLocked();
+            // Force the allDrawn flag, because we want to start
+            // this guy's animations regardless of whether it's
+            // gotten drawn.
+            wtoken.allDrawn = true;
+            wtoken.deferClearAllDrawn = false;
+            // Ensure that apps that are mid-starting are also scheduled to have their
+            // starting windows removed after the animation is complete
+            if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
+                mService.scheduleRemoveStartingWindowLocked(wtoken);
+            }
+            mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+            if (animLp != null) {
+                int layer = -1;
+                for (int j = 0; j < wtoken.windows.size(); j++) {
+                    WindowState win = wtoken.windows.get(j);
+                    if (win.mWinAnimator.mAnimLayer > layer) {
+                        layer = win.mWinAnimator.mAnimLayer;
+                    }
+                }
+                if (topClosingApp == null || layer > topClosingLayer) {
+                    topClosingApp = wtoken;
+                    topClosingLayer = layer;
+                }
+            }
+        }
+
+        AppWindowToken topOpeningApp = null;
+        appsCount = mService.mOpeningApps.size();
+        for (i = 0; i < appsCount; i++) {
+            AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
+            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "Now opening app" + wtoken);
+
+            if (!appAnimator.usingTransferredAnimation) {
+                appAnimator.clearThumbnail();
+                appAnimator.animation = null;
+            }
+            wtoken.inPendingTransaction = false;
+            if (!mService.setTokenVisibilityLocked(
+                    wtoken, animLp, true, transit, false, voiceInteraction)){
+                // This token isn't going to be animating. Add it to the list of tokens to
+                // be notified of app transition complete since the notification will not be
+                // sent be the app window animator.
+                mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
+            }
+            wtoken.updateReportedVisibilityLocked();
+            wtoken.waitingToShow = false;
+
+            appAnimator.mAllAppWinAnimators.clear();
+            final int windowsCount = wtoken.allAppWindows.size();
+            for (int j = 0; j < windowsCount; j++) {
+                appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+            }
+            mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+            mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+            int topOpeningLayer = 0;
+            if (animLp != null) {
+                int layer = -1;
+                for (int j = 0; j < wtoken.windows.size(); j++) {
+                    WindowState win = wtoken.windows.get(j);
+                    if (win.mWinAnimator.mAnimLayer > layer) {
+                        layer = win.mWinAnimator.mAnimLayer;
+                    }
+                }
+                if (topOpeningApp == null || layer > topOpeningLayer) {
+                    topOpeningApp = wtoken;
+                    topOpeningLayer = layer;
+                }
+            }
+            createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
+        }
+
+        AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
+                topOpeningApp.mAppAnimator;
+        AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
+                topClosingApp.mAppAnimator;
+
+        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
+        mService.mAppTransition.postAnimationCallback();
+        mService.mAppTransition.clear();
+
+        mService.mOpeningApps.clear();
+        mService.mClosingApps.clear();
+
+        // This has changed the visibility of windows, so perform
+        // a new layout to get them all up-to-date.
+        mService.getDefaultDisplayContentLocked().layoutNeeded = true;
+
+        // TODO(multidisplay): IMEs are only supported on the default display.
+        if (windows == mService.getDefaultWindowListLocked()
+                && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
+            mService.assignLayersLocked(windows);
+        }
+        mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+                true /*updateInputWindows*/);
+        mService.mFocusMayChange = false;
+        mService.notifyActivityDrawnForKeyguard();
+        return FINISH_LAYOUT_REDO_LAYOUT
+                | FINISH_LAYOUT_REDO_CONFIG;
+
+    }
+
+    private boolean transitionGoodToGo(int appsCount) {
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                "Checking " + appsCount + " opening apps (frozen="
+                        + mService.mDisplayFrozen + " timeout="
+                        + mService.mAppTransition.isTimeout() + ")...");
+        if (!mService.mAppTransition.isTimeout()) {
+            for (int i = 0; i < appsCount; i++) {
+                AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                        "Check opening app=" + wtoken + ": allDrawn="
+                        + wtoken.allDrawn + " startingDisplayed="
+                        + wtoken.startingDisplayed + " startingMoved="
+                        + wtoken.startingMoved);
+                if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
+                    return false;
+                }
+            }
+
+            // If the wallpaper is visible, we need to check it's ready too.
+            return !mWallpaperControllerLocked.isWallpaperVisible() ||
+                    mWallpaperControllerLocked.wallpaperTransitionReady();
+        }
+        return true;
+    }
+
+    private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
+            boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
+            WindowState upperWallpaperTarget) {
+        // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
+        final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
+        final WindowState oldWallpaper =
+                mWallpaperControllerLocked.isWallpaperTargetAnimating()
+                        ? null : wallpaperTarget;
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                "New wallpaper target=" + wallpaperTarget
+                        + ", oldWallpaper=" + oldWallpaper
+                        + ", lower target=" + lowerWallpaperTarget
+                        + ", upper target=" + upperWallpaperTarget);
+        mService.mAnimateWallpaperWithTarget = false;
+        if (closingAppHasWallpaper && openingAppHasWallpaper) {
+            if (DEBUG_APP_TRANSITIONS)
+                Slog.v(TAG, "Wallpaper animation!");
+            switch (transit) {
+                case AppTransition.TRANSIT_ACTIVITY_OPEN:
+                case AppTransition.TRANSIT_TASK_OPEN:
+                case AppTransition.TRANSIT_TASK_TO_FRONT:
+                    transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
+                    break;
+                case AppTransition.TRANSIT_ACTIVITY_CLOSE:
+                case AppTransition.TRANSIT_TASK_CLOSE:
+                case AppTransition.TRANSIT_TASK_TO_BACK:
+                    transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
+                    break;
+            }
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "New transit: " + AppTransition.appTransitionToString(transit));
+        } else if ((oldWallpaper != null) && !mService.mOpeningApps.isEmpty()
+                && !mService.mOpeningApps.contains(oldWallpaper.mAppToken)) {
+            // We are transitioning from an activity with
+            // a wallpaper to one without.
+            transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "New transit away from wallpaper: "
+                    + AppTransition.appTransitionToString(transit));
+        } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()) {
+            // We are transitioning from an activity without
+            // a wallpaper to now showing the wallpaper
+            transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "New transit into wallpaper: "
+                    + AppTransition.appTransitionToString(transit));
+        } else {
+            mService.mAnimateWallpaperWithTarget = true;
+        }
+        return transit;
+    }
+
+    /**
+     * @param w WindowState this method is applied to.
+     * @param innerDw Width of app window.
+     * @param innerDh Height of app window.
+     */
+    private void handleNotObscuredLocked(final WindowState w, final int innerDw, final int innerDh) {
+        final WindowManager.LayoutParams attrs = w.mAttrs;
+        final int attrFlags = attrs.flags;
+        final boolean canBeSeen = w.isDisplayedLw();
+        final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
+
+        if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
+            // This window completely covers everything behind it,
+            // so we want to leave all of them as undimmed (for
+            // performance reasons).
+            mObscured = true;
+        }
+
+        if (w.mHasSurface) {
+            if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
+                mHoldScreen = w.mSession;
+            }
+            if (!mSyswin && w.mAttrs.screenBrightness >= 0
+                    && mScreenBrightness < 0) {
+                mScreenBrightness = w.mAttrs.screenBrightness;
+            }
+            if (!mSyswin && w.mAttrs.buttonBrightness >= 0
+                    && mButtonBrightness < 0) {
+                mButtonBrightness = w.mAttrs.buttonBrightness;
+            }
+            if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
+                    && mUserActivityTimeout < 0) {
+                mUserActivityTimeout = w.mAttrs.userActivityTimeout;
+            }
+
+            final int type = attrs.type;
+            if (canBeSeen
+                    && (type == TYPE_SYSTEM_DIALOG
+                     || type == TYPE_SYSTEM_ERROR
+                     || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
+                mSyswin = true;
+            }
+
+            if (canBeSeen) {
+                // This function assumes that the contents of the default display are
+                // processed first before secondary displays.
+                final DisplayContent displayContent = w.getDisplayContent();
+                if (displayContent != null && displayContent.isDefaultDisplay) {
+                    // While a dream or keyguard is showing, obscure ordinary application
+                    // content on secondary displays (by forcibly enabling mirroring unless
+                    // there is other content we want to show) but still allow opaque
+                    // keyguard dialogs to be shown.
+                    if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+                        mObscureApplicationContentOnSecondaryDisplays = true;
+                    }
+                    mDisplayHasContent = true;
+                } else if (displayContent != null &&
+                        (!mObscureApplicationContentOnSecondaryDisplays
+                        || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
+                    // Allow full screen keyguard presentation dialogs to be seen.
+                    mDisplayHasContent = true;
+                }
+                if (mPreferredRefreshRate == 0
+                        && w.mAttrs.preferredRefreshRate != 0) {
+                    mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
+                }
+                if (mPreferredModeId == 0
+                        && w.mAttrs.preferredDisplayModeId != 0) {
+                    mPreferredModeId = w.mAttrs.preferredDisplayModeId;
+                }
+            }
+        }
+    }
+
+    private void updateAllDrawnLocked(DisplayContent displayContent) {
+        // See if any windows have been drawn, so they (and others
+        // associated with them) can now be shown.
+        ArrayList<TaskStack> stacks = displayContent.getStacks();
+        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
+            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                    final AppWindowToken wtoken = tokens.get(tokenNdx);
+                    if (!wtoken.allDrawn) {
+                        int numInteresting = wtoken.numInterestingWindows;
+                        if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+                            if (DEBUG_VISIBILITY)
+                                Slog.v(TAG, "allDrawn: " + wtoken
+                                    + " interesting=" + numInteresting
+                                    + " drawn=" + wtoken.numDrawnWindows);
+                            wtoken.allDrawn = true;
+                            // Force an additional layout pass where WindowStateAnimator#
+                            // commitFinishDrawingLocked() will call performShowLocked().
+                            displayContent.layoutNeeded = true;
+                            mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
+                                    wtoken.token).sendToTarget();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static int toBrightnessOverride(float value) {
+        return (int)(value * PowerManager.BRIGHTNESS_ON);
+    }
+
+    private void processApplicationsAnimatingInPlace(int transit) {
+        if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
+            // Find the focused window
+            final WindowState win = mService.findFocusedWindowLocked(
+                    mService.getDefaultDisplayContentLocked());
+            if (win != null) {
+                final AppWindowToken wtoken = win.mAppToken;
+                final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+                if (DEBUG_APP_TRANSITIONS)
+                    Slog.v(TAG, "Now animating app in place " + wtoken);
+                appAnimator.clearThumbnail();
+                appAnimator.animation = null;
+                mService.updateTokenInPlaceLocked(wtoken, transit);
+                wtoken.updateReportedVisibilityLocked();
+
+                appAnimator.mAllAppWinAnimators.clear();
+                final int N = wtoken.allAppWindows.size();
+                for (int j = 0; j < N; j++) {
+                    appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+                }
+                mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+                mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+            }
+        }
+    }
+
+    private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
+            int openingLayer, int closingLayer) {
+        AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
+        if (openingAppAnimator == null || openingAppAnimator.animation == null) {
+            return;
+        }
+        final int taskId = appToken.mTask.mTaskId;
+        Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
+        if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
+            return;
+        }
+        // This thumbnail animation is very special, we need to have
+        // an extra surface with the thumbnail included with the animation.
+        Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
+        try {
+            // TODO(multi-display): support other displays
+            final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
+            final Display display = displayContent.getDisplay();
+            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+
+            // Create a new surface for the thumbnail
+            SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
+                    "thumbnail anim", dirty.width(), dirty.height(),
+                    PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            surfaceControl.setLayerStack(display.getLayerStack());
+            if (SHOW_TRANSACTIONS) {
+                Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
+            }
+
+            // Draw the thumbnail onto the surface
+            Surface drawSurface = new Surface();
+            drawSurface.copyFrom(surfaceControl);
+            Canvas c = drawSurface.lockCanvas(dirty);
+            c.drawBitmap(thumbnailHeader, 0, 0, null);
+            drawSurface.unlockCanvasAndPost(c);
+            drawSurface.release();
+
+            // Get the thumbnail animation
+            Animation anim;
+            if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
+                // If this is a multi-window scenario, we use the windows frame as
+                // destination of the thumbnail header animation. If this is a full screen
+                // window scenario, we use the whole display as the target.
+                WindowState win = appToken.findMainWindow();
+                Rect appRect = win != null ? win.getContentFrameLw() :
+                        new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+                // For the new aspect-scaled transition, we want it to always show
+                // above the animating opening/closing window, and we want to
+                // synchronize its thumbnail surface with the surface for the
+                // open/close animation (only on the way down)
+                anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
+                        thumbnailHeader, taskId);
+                Log.d(TAG, "assigning thumbnail force above layer: "
+                        + openingLayer + " " + closingLayer);
+                openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
+                openingAppAnimator.deferThumbnailDestruction =
+                        !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
+            } else {
+                anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
+                        displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
+            }
+            anim.restrictDuration(MAX_ANIMATION_DURATION);
+            anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
+
+            openingAppAnimator.thumbnail = surfaceControl;
+            openingAppAnimator.thumbnailLayer = openingLayer;
+            openingAppAnimator.thumbnailAnimation = anim;
+            mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
+            openingAppAnimator.thumbnailX = mTmpStartRect.left;
+            openingAppAnimator.thumbnailY = mTmpStartRect.top;
+        } catch (Surface.OutOfResourcesException e) {
+            Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
+                    + dirty.width() + " h=" + dirty.height(), e);
+            openingAppAnimator.clearThumbnail();
+        }
+    }
+
+    boolean copyAnimToLayoutParamsLocked() {
+        boolean doRequest = false;
+
+        final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
+        if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
+            mUpdateRotation = true;
+            doRequest = true;
+        }
+        if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
+            mWallpaperMayChange = true;
+            doRequest = true;
+        }
+        if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
+            mWallpaperForceHidingChanged = true;
+            doRequest = true;
+        }
+        if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
+            mOrientationChangeComplete = false;
+        } else {
+            mOrientationChangeComplete = true;
+            mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
+            if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+                doRequest = true;
+            }
+        }
+        if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
+            mService.mTurnOnScreen = true;
+        }
+        if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
+            mWallpaperActionPending = true;
+        }
+
+        return doRequest;
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b57e3ea..0202309 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -96,6 +96,8 @@
 import android.security.KeyChain.KeyChainConnection;
 import android.service.persistentdata.PersistentDataBlockManager;
 import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
@@ -140,8 +142,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -197,7 +197,7 @@
 
     private static final Set<String> DEVICE_OWNER_USER_RESTRICTIONS;
     static {
-        DEVICE_OWNER_USER_RESTRICTIONS = new HashSet();
+        DEVICE_OWNER_USER_RESTRICTIONS = new ArraySet<>();
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_USB_FILE_TRANSFER);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_TETHERING);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_NETWORK_RESET);
@@ -218,7 +218,7 @@
     // owner and profile owner.
     private static final Set<String> IMMUTABLE_USER_RESTRICTIONS;
     static {
-        IMMUTABLE_USER_RESTRICTIONS = new HashSet();
+        IMMUTABLE_USER_RESTRICTIONS = new ArraySet<>();
         IMMUTABLE_USER_RESTRICTIONS.add(UserManager.DISALLOW_WALLPAPER);
     }
 
@@ -227,16 +227,16 @@
     private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
     private static final Set<String> GLOBAL_SETTINGS_DEPRECATED;
     static {
-        SECURE_SETTINGS_WHITELIST = new HashSet();
+        SECURE_SETTINGS_WHITELIST = new ArraySet<>();
         SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
         SECURE_SETTINGS_WHITELIST.add(Settings.Secure.SKIP_FIRST_USE_HINTS);
         SECURE_SETTINGS_WHITELIST.add(Settings.Secure.INSTALL_NON_MARKET_APPS);
 
-        SECURE_SETTINGS_DEVICEOWNER_WHITELIST = new HashSet();
+        SECURE_SETTINGS_DEVICEOWNER_WHITELIST = new ArraySet<>();
         SECURE_SETTINGS_DEVICEOWNER_WHITELIST.addAll(SECURE_SETTINGS_WHITELIST);
         SECURE_SETTINGS_DEVICEOWNER_WHITELIST.add(Settings.Secure.LOCATION_MODE);
 
-        GLOBAL_SETTINGS_WHITELIST = new HashSet();
+        GLOBAL_SETTINGS_WHITELIST = new ArraySet<>();
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.ADB_ENABLED);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE);
@@ -246,7 +246,7 @@
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN);
 
-        GLOBAL_SETTINGS_DEPRECATED = new HashSet();
+        GLOBAL_SETTINGS_DEPRECATED = new ArraySet<>();
         GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON);
         GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
         GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.MODE_RINGER);
@@ -326,7 +326,7 @@
         boolean mUserSetupComplete = false;
         int mPermissionPolicy;
 
-        final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<>();
+        final ArrayMap<ComponentName, ActiveAdmin> mAdminMap = new ArrayMap<>();
         final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>();
         final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>();
 
@@ -494,7 +494,7 @@
             }
         }
 
-        Set<String> accountTypesWithManagementDisabled = new HashSet<String>();
+        Set<String> accountTypesWithManagementDisabled = new ArraySet<>();
 
         // The list of permitted accessibility services package namesas set by a profile
         // or device owner. Null means all accessibility services are allowed, empty means
@@ -511,7 +511,7 @@
         String globalProxySpec = null;
         String globalProxyExclusionList = null;
 
-        HashMap<String, TrustAgentInfo> trustAgentInfos = new HashMap<String, TrustAgentInfo>();
+        ArrayMap<String, TrustAgentInfo> trustAgentInfos = new ArrayMap<>();
 
         List<String> crossProfileWidgetProviders;
 
@@ -834,7 +834,7 @@
                 throws XmlPullParserException, IOException {
             int outerDepthDAM = parser.getDepth();
             int typeDAM;
-            Set<String> result = new HashSet<String>();
+            Set<String> result = new ArraySet<>();
             while ((typeDAM=parser.next()) != END_DOCUMENT
                     && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
                 if (typeDAM == END_TAG || typeDAM == TEXT) {
@@ -850,11 +850,11 @@
             return result;
         }
 
-        private HashMap<String, TrustAgentInfo> getAllTrustAgentInfos(
+        private ArrayMap<String, TrustAgentInfo> getAllTrustAgentInfos(
                 XmlPullParser parser, String tag) throws XmlPullParserException, IOException {
             int outerDepthDAM = parser.getDepth();
             int typeDAM;
-            HashMap<String, TrustAgentInfo> result = new HashMap<String, TrustAgentInfo>();
+            final ArrayMap<String, TrustAgentInfo> result = new ArrayMap<>();
             while ((typeDAM=parser.next()) != END_DOCUMENT
                     && (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
                 if (typeDAM == END_TAG || typeDAM == TEXT) {
@@ -1805,14 +1805,14 @@
         Set<Integer> usersWithData;
         synchronized(this) {
             usersWithProfileOwners = mOwners.getProfileOwnerKeys();
-            usersWithData = new HashSet<Integer>();
+            usersWithData = new ArraySet<>();
             for (int i = 0; i < mUserData.size(); i++) {
                 usersWithData.add(mUserData.keyAt(i));
             }
         }
         List<UserInfo> allUsers = mUserManager.getUsers();
 
-        Set<Integer> deletedUsers = new HashSet<Integer>();
+        Set<Integer> deletedUsers = new ArraySet<>();
         deletedUsers.addAll(usersWithProfileOwners);
         deletedUsers.addAll(usersWithData);
         for (UserInfo userInfo : allUsers) {
@@ -5696,7 +5696,7 @@
         synchronized (this) {
             DevicePolicyData policy = getUserData(userId);
             final int N = policy.mAdminList.size();
-            HashSet<String> resultSet = new HashSet<String>();
+            ArraySet<String> resultSet = new ArraySet<>();
             for (int i = 0; i < N; i++) {
                 ActiveAdmin admin = policy.mAdminList.get(i);
                 resultSet.addAll(admin.accountTypesWithManagementDisabled);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 7a468ce..1656716 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -27,6 +27,7 @@
 import android.os.Environment;
 import android.os.RemoteException;
 import android.os.UserManager;
+import android.util.ArrayMap;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Slog;
@@ -44,7 +45,6 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -89,7 +89,7 @@
     private OwnerInfo mDeviceInitializer;
 
     // Internal state for the profile owner packages.
-    private final HashMap<Integer, OwnerInfo> mProfileOwners = new HashMap<Integer, OwnerInfo>();
+    private final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>();
 
     // Local system update policy controllable by device owner.
     private SystemUpdatePolicy mSystemUpdatePolicy;
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index a91ddb8..cbf8fc2 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -55,6 +55,7 @@
     public static final int MIN_PACKET_LENGTH_L3 = MIN_PACKET_LENGTH_BOOTP + 20 + 8;
     public static final int MIN_PACKET_LENGTH_L2 = MIN_PACKET_LENGTH_L3 + 14;
 
+    public static final int HWADDR_LEN = 16;
     public static final int MAX_OPTION_LEN = 255;
     /**
      * IP layer definitions.
@@ -399,7 +400,7 @@
         buf.put(mRelayIp.getAddress());
         buf.put(mClientMac);
         buf.position(buf.position() +
-                     (16 - mClientMac.length) // pad addr to 16 bytes
+                     (HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
                      + 64     // empty server host name (64 bytes)
                      + 128);  // empty boot file name (128 bytes)
         buf.putInt(0x63825363); // magic number
@@ -786,7 +787,7 @@
 
         byte type = packet.get();
         byte hwType = packet.get();
-        byte addrLen = packet.get();
+        int addrLen = packet.get() & 0xff;
         byte hops = packet.get();
         transactionId = packet.getInt();
         secs = packet.getShort();
@@ -807,6 +808,16 @@
             return null;
         }
 
+        // Some DHCP servers have been known to announce invalid client hardware address values such
+        // as 0xff. The legacy DHCP client accepted these becuause it does not check the length at
+        // all but only checks that the interface MAC address matches the first bytes of the address
+        // in the packets. We're a bit stricter: if the length is obviously invalid (i.e., bigger
+        // than the size of the field), we fudge it to 6 (Ethernet). http://b/23725795
+        // TODO: evaluate whether to make this test more liberal.
+        if (addrLen > HWADDR_LEN) {
+            addrLen = ETHER_BROADCAST.length;
+        }
+
         clientMac = new byte[addrLen];
         packet.get(clientMac);
 
diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
index da1df1a..cd3b8bb 100644
--- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
@@ -333,6 +333,76 @@
     }
 
     @SmallTest
+    public void testBadHwaddrLength() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
+            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"
+        ).toCharArray(), false));
+        String expectedClientMac = "30766FF2A90C";
+
+        final int hwAddrLenOffset = 20 + 8 + 2;
+        assertEquals(6, packet.get(hwAddrLenOffset));
+
+        // Expect the expected.
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(6, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+
+        // Reduce the hardware address length and verify that it shortens the client MAC.
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) 5);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(5, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac.substring(0, 10),
+                HexDump.toHexString(offerPacket.getClientMac()));
+
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) 3);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(3, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac.substring(0, 6),
+                HexDump.toHexString(offerPacket.getClientMac()));
+
+        // Set the the hardware address length to 0xff and verify that we a) don't treat it as -1
+        // and crash, and b) hardcode it to 6.
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) -1);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(6, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+
+        // Set the the hardware address length to a positive invalid value (> 16) and verify that we
+        // hardcode it to 6.
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) 17);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(6, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+    }
+
+    @SmallTest
     public void testPadAndOverloadedOptionsOffer() throws Exception {
         // A packet observed in the real world that is interesting for two reasons:
         //
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
index fd9fc98..51e14d3 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
@@ -54,7 +54,7 @@
      * Timeout in which we are waiting for the system to start the mock
      * accessibility services.
      */
-    private static final long TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES = 300;
+    private static final long TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES = 1000;
 
     /**
      * Timeout used for testing that a service is notified only upon a
@@ -68,6 +68,12 @@
     private IAccessibilityManager mManagerService;
 
     @Override
+    protected void setUp() throws Exception {
+        // Reset the state.
+        ensureOnlyMockServicesEnabled(getContext(), false, false);
+    }
+
+    @Override
     public void setContext(Context context) {
         super.setContext(context);
         if (MyFirstMockAccessibilityService.sComponentName == null) {
@@ -92,6 +98,9 @@
 
     @LargeTest
     public void testAddClient_AccessibilityDisabledThenEnabled() throws Exception {
+        // at least some service must be enabled, otherwise accessibility will always be disabled.
+        ensureOnlyMockServicesEnabled(mContext, true, false);
+
         // make sure accessibility is disabled
         ensureAccessibilityEnabled(mContext, false);
 
@@ -99,7 +108,8 @@
         MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
 
         // invoke the method under test
-        final int stateFlagsDisabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+        final int stateFlagsDisabled =
+                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
         boolean enabledAccessibilityDisabled =
             (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -111,11 +121,11 @@
         ensureAccessibilityEnabled(mContext, true);
 
         // invoke the method under test
-        final int stateFlagsEnabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+        final int stateFlagsEnabled =
+                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
         boolean enabledAccessibilityEnabled =
             (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
-
         // check expected result
         assertTrue("The client must be enabled since accessibility is enabled.",
                 enabledAccessibilityEnabled);
@@ -123,6 +133,9 @@
 
     @LargeTest
     public void testAddClient_AccessibilityEnabledThenDisabled() throws Exception {
+        // at least some service must be enabled, otherwise accessibility will always be disabled.
+        ensureOnlyMockServicesEnabled(mContext, true, false);
+
         // enable accessibility before registering the client
         ensureAccessibilityEnabled(mContext, true);
 
@@ -130,7 +143,8 @@
         MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
 
         // invoke the method under test
-        final int stateFlagsEnabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+        final int stateFlagsEnabled =
+                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
         boolean enabledAccessibilityEnabled =
             (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -142,7 +156,8 @@
         ensureAccessibilityEnabled(mContext, false);
 
         // invoke the method under test
-        final int stateFlagsDisabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+        final int stateFlagsDisabled =
+                mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
         boolean enabledAccessibilityDisabled =
             (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
 
@@ -162,7 +177,7 @@
 
         // look for the two mock services
         for (AccessibilityServiceInfo info : mManagerService.getInstalledAccessibilityServiceList(
-                UserHandle.USER_OWNER)) {
+                UserHandle.USER_CURRENT)) {
             ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
             if (packageName.equals(serviceInfo.packageName)) {
                 if (firstMockServiceClassName.equals(serviceInfo.name)) {
@@ -181,12 +196,12 @@
     @LargeTest
     public void testSendAccessibilityEvent_OneService_MatchingPackageAndEventType()
             throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility service
         ensureOnlyMockServicesEnabled(mContext, true, false);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the mock service
         MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
         service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -203,7 +218,7 @@
         service.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(service);
@@ -211,12 +226,12 @@
 
     @LargeTest
     public void testSendAccessibilityEvent_OneService_NotMatchingPackage() throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility service
         ensureOnlyMockServicesEnabled(mContext, true, false);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the mock service
         MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
         service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -233,7 +248,7 @@
         service.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(service);
@@ -241,12 +256,12 @@
 
     @LargeTest
     public void testSendAccessibilityEvent_OneService_NotMatchingEventType() throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility service
         ensureOnlyMockServicesEnabled(mContext, true, false);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the mock service
         MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
         service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -263,7 +278,7 @@
         service.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(service);
@@ -271,12 +286,12 @@
 
     @LargeTest
     public void testSendAccessibilityEvent_OneService_NotifivationAfterTimeout() throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility service
         ensureOnlyMockServicesEnabled(mContext, true, false);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the mock service
         MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
         AccessibilityServiceInfo info = MockAccessibilityService.createDefaultInfo();
@@ -299,8 +314,8 @@
         service.replay();
 
         // send the events
-        mManagerService.sendAccessibilityEvent(firstEvent, UserHandle.USER_OWNER);
-        mManagerService.sendAccessibilityEvent(secondEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(firstEvent, UserHandle.USER_CURRENT);
+        mManagerService.sendAccessibilityEvent(secondEvent, UserHandle.USER_CURRENT);
 
         // wait for #sendAccessibilityEvent to reach the backing service
         Thread.sleep(TIMEOUT_BINDER_CALL);
@@ -322,12 +337,12 @@
     @LargeTest
     public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_DiffFeedback()
             throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility services
         ensureOnlyMockServicesEnabled(mContext, true, true);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the first mock service
         MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
         AccessibilityServiceInfo firstInfo = MockAccessibilityService.createDefaultInfo();
@@ -356,7 +371,7 @@
         secondService.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(firstService);
@@ -366,12 +381,12 @@
     @LargeTest
     public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType()
             throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility services
         ensureOnlyMockServicesEnabled(mContext, true, true);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the first mock service
         MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
         firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -395,7 +410,7 @@
         secondService.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(firstService);
@@ -405,12 +420,12 @@
     @LargeTest
     public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_OneDefault()
             throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility services
         ensureOnlyMockServicesEnabled(mContext, true, true);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the first mock service
         MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
         AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
@@ -436,7 +451,7 @@
         secondService.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(firstService);
@@ -446,12 +461,12 @@
     @LargeTest
     public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_TwoDefault()
             throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility services
         ensureOnlyMockServicesEnabled(mContext, true, true);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the first mock service
         MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
         AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
@@ -479,7 +494,7 @@
         secondService.replay();
 
         // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(firstService);
@@ -488,12 +503,12 @@
 
     @LargeTest
     public void testInterrupt() throws Exception {
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
         // enable the mock accessibility services
         ensureOnlyMockServicesEnabled(mContext, true, true);
 
+        // set the accessibility setting value
+        ensureAccessibilityEnabled(mContext, true);
+
         // configure the first mock service
         MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
         firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -514,7 +529,7 @@
         secondService.replay();
 
         // call the method under test
-        mManagerService.interrupt(UserHandle.USER_OWNER);
+        mManagerService.interrupt(UserHandle.USER_CURRENT);
 
         // verify if all expected methods have been called
         assertMockServiceVerifiedWithinTimeout(firstService);
@@ -534,7 +549,7 @@
         sentEvent.setContentDescription("ContentDescription");
         sentEvent.setCurrentItemIndex(1);
         sentEvent.setEnabled(true);
-        sentEvent.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
+        sentEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
         sentEvent.setEventTime(1000);
         sentEvent.setFromIndex(1);
         sentEvent.setFullScreen(true);
@@ -568,8 +583,8 @@
      * @throws Exception If any error occurs.
      */
     private void ensureAccessibilityEnabled(Context context, boolean enabled) throws Exception {
-        boolean isEnabled = (Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1 ? true : false);
+        boolean isEnabled = Settings.Secure.getInt(context.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
 
         if (isEnabled == enabled) {
             return;
@@ -608,13 +623,14 @@
             servicesToEnable.append(MySecondMockAccessibilityService.sComponentName).append(":");
         }
 
+        Settings.Secure.putString(context.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
+
+        // Optimization. If things will not change, we don't have to do anything.
         if (servicesToEnable.equals(enabledServices)) {
             return;
         }
 
-        Settings.Secure.putString(context.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
-
         // we have enabled the services of interest and need to wait until they
         // are instantiated and started (if needed) and the system binds to them
         boolean firstMockServiceOK = false;
@@ -664,13 +680,13 @@
             throws Exception {
         Exception lastVerifyException = null;
         long beginTime = SystemClock.uptimeMillis();
-        long pollTmeout = TIMEOUT_BINDER_CALL / 5;
+        long pollTimeout = TIMEOUT_BINDER_CALL / 5;
 
         // poll until the timeout has elapsed
         while (SystemClock.uptimeMillis() - beginTime < TIMEOUT_BINDER_CALL) {
             // sleep first since immediate call will always fail
             try {
-                Thread.sleep(pollTmeout);
+                Thread.sleep(pollTimeout);
             } catch (InterruptedException ie) {
                 /* ignore */
             }
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
index e7366ea..026a2ad 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
@@ -16,14 +16,11 @@
 
 package com.android.server;
 
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reportMatcher;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-
-import org.easymock.IArgumentMatcher;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.os.UserHandle;
@@ -35,6 +32,9 @@
 import android.view.accessibility.IAccessibilityManager;
 import android.view.accessibility.IAccessibilityManagerClient;
 
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -49,78 +49,65 @@
      */
     public static final long TIMEOUT_BINDER_CALL = 50;
 
-    /**
-     * The reusable mock {@link IAccessibilityManager}.
-     */
-    private final IAccessibilityManager mMockServiceInterface =
-        createStrictMock(IAccessibilityManager.class);
+    @Mock
+    private IAccessibilityManager mMockService;
 
     @Override
     public void setUp() throws Exception {
-        reset(mMockServiceInterface);
+        MockitoAnnotations.initMocks(this);
+    }
+
+    private AccessibilityManager createManager(boolean enabled) throws Exception {
+        if (enabled) {
+            when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
+                    .thenReturn(AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
+        } else {
+            when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
+                    .thenReturn(0);
+        }
+
+        AccessibilityManager manager =
+                new AccessibilityManager(mContext, mMockService, UserHandle.USER_CURRENT);
+
+        verify(mMockService).addClient(any(IAccessibilityManagerClient.class), anyInt());
+
+        return manager;
     }
 
     @MediumTest
     public void testGetAccessibilityServiceList() throws Exception {
         // create a list of installed accessibility services the mock service returns
-        List<AccessibilityServiceInfo> expectedServices = new ArrayList<AccessibilityServiceInfo>();
+        List<AccessibilityServiceInfo> expectedServices = new ArrayList<>();
         AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
         accessibilityServiceInfo.packageNames = new String[] { "foo.bar" };
         expectedServices.add(accessibilityServiceInfo);
 
         // configure the mock service behavior
-        IAccessibilityManager mockServiceInterface = mMockServiceInterface;
-        expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
-                UserHandle.USER_OWNER)).andReturn(
-                AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
-        expect(mockServiceInterface.getInstalledAccessibilityServiceList(UserHandle.USER_OWNER))
-                .andReturn(expectedServices);
-        replay(mockServiceInterface);
+        when(mMockService.getInstalledAccessibilityServiceList(anyInt()))
+                .thenReturn(expectedServices);
 
         // invoke the method under test
-        AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
-                UserHandle.USER_OWNER);
+        AccessibilityManager manager = createManager(true);
         List<AccessibilityServiceInfo> receivedServices =
-            manager.getInstalledAccessibilityServiceList();
+                manager.getInstalledAccessibilityServiceList();
 
+        verify(mMockService).getInstalledAccessibilityServiceList(UserHandle.USER_CURRENT);
         // check expected result (list equals() compares it contents as well)
-        assertEquals("All expected services must be returned", receivedServices, expectedServices);
-
-        // verify the mock service was properly called
-        verify(mockServiceInterface);
+        assertEquals("All expected services must be returned", expectedServices, receivedServices);
     }
 
     @MediumTest
     public void testInterrupt() throws Exception {
-        // configure the mock service behavior
-        IAccessibilityManager mockServiceInterface = mMockServiceInterface;
-        expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
-                UserHandle.USER_OWNER)).andReturn(
-                        AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
-        mockServiceInterface.interrupt(UserHandle.USER_OWNER);
-        replay(mockServiceInterface);
-
-        // invoke the method under test
-        AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
-                UserHandle.USER_OWNER);
+        AccessibilityManager manager = createManager(true);
         manager.interrupt();
 
-        // verify the mock service was properly called
-        verify(mockServiceInterface);
+        verify(mMockService).interrupt(UserHandle.USER_CURRENT);
     }
 
     @LargeTest
     public void testIsEnabled() throws Exception {
-        // configure the mock service behavior
-        IAccessibilityManager mockServiceInterface = mMockServiceInterface;
-        expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
-                UserHandle.USER_OWNER)).andReturn(
-                        AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
-        replay(mockServiceInterface);
-
         // invoke the method under test
-        AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
-                UserHandle.USER_OWNER);
+        AccessibilityManager manager = createManager(true);
         boolean isEnabledServiceEnabled = manager.isEnabled();
 
         // check expected result
@@ -138,63 +125,32 @@
         // check expected result
         assertFalse("Must be disabled since the mock service is disabled",
                 isEnabledServcieDisabled);
-
-        // verify the mock service was properly called
-        verify(mockServiceInterface);
     }
 
     @MediumTest
     public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception {
-        // create an event to be dispatched
         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
 
-        // configure the mock service behavior
-        IAccessibilityManager mockServiceInterface = mMockServiceInterface;
-        expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
-                UserHandle.USER_OWNER)).andReturn(
-                        AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
-        expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent),
-                UserHandle.USER_OWNER)).andReturn(true);
-        expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent),
-                UserHandle.USER_OWNER)).andReturn(false);
-        replay(mockServiceInterface);
+        when(mMockService.sendAccessibilityEvent(eq(sentEvent), anyInt()))
+                .thenReturn(true  /* should recycle event object */)
+                .thenReturn(false /* should not recycle event object */);
 
-        // invoke the method under test (manager and service in different processes)
-        AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
-                UserHandle.USER_OWNER);
+        AccessibilityManager manager = createManager(true);
         manager.sendAccessibilityEvent(sentEvent);
 
-        // check expected result
-        AccessibilityEvent nextEventDifferentProcesses = AccessibilityEvent.obtain();
-        assertSame("The manager and the service are in different processes, so the event must be " +
-                "recycled", sentEvent, nextEventDifferentProcesses);
+        assertSame("The event should be recycled.", sentEvent, AccessibilityEvent.obtain());
 
-        // invoke the method under test (manager and service in the same process)
         manager.sendAccessibilityEvent(sentEvent);
 
-        // check expected result
-        AccessibilityEvent nextEventSameProcess = AccessibilityEvent.obtain();
-        assertNotSame("The manager and the service are in the same process, so the event must not" +
-                "be recycled", sentEvent, nextEventSameProcess);
-
-        // verify the mock service was properly called
-        verify(mockServiceInterface);
+        assertNotSame("The event should not be recycled.", sentEvent, AccessibilityEvent.obtain());
     }
 
     @MediumTest
     public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception {
-        // create an event to be dispatched
         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
 
-        // configure the mock service behavior
-        IAccessibilityManager mockServiceInterface = mMockServiceInterface;
-        expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
-                UserHandle.USER_OWNER)).andReturn(0);
-        replay(mockServiceInterface);
+        AccessibilityManager manager = createManager(false  /* disabled */);
 
-        // invoke the method under test (accessibility disabled)
-        AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
-                UserHandle.USER_OWNER);
         try {
             manager.sendAccessibilityEvent(sentEvent);
             fail("No accessibility events are sent if accessibility is disabled");
@@ -202,73 +158,5 @@
             // check expected result
             assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage());
         }
-
-        // verify the mock service was properly called
-        verify(mockServiceInterface);
-    }
-
-    /**
-     * Determines if an {@link AccessibilityEvent} passed as a method argument
-     * matches expectations.
-     *
-     * @param matched The event to check.
-     * @return True if expectations are matched.
-     */
-    private static AccessibilityEvent eqAccessibilityEvent(AccessibilityEvent matched) {
-        reportMatcher(new AccessibilityEventMather(matched));
-        return null;
-    }
-
-    /**
-     * Determines if an {@link IAccessibilityManagerClient} passed as a method argument
-     * matches expectations which in this case are that any instance is accepted.
-     *
-     * @return <code>null</code>.
-     */
-    private static IAccessibilityManagerClient anyIAccessibilityManagerClient() {
-        reportMatcher(new AnyIAccessibilityManagerClientMather());
-        return null;
-    }
-
-    /**
-     * Matcher for {@link AccessibilityEvent}s.
-     */
-    private static class AccessibilityEventMather implements IArgumentMatcher {
-        private AccessibilityEvent mExpectedEvent;
-
-        public AccessibilityEventMather(AccessibilityEvent expectedEvent) {
-            mExpectedEvent = expectedEvent;
-        }
-
-        public boolean matches(Object matched) {
-            if (!(matched instanceof AccessibilityEvent)) {
-                return false;
-            }
-            AccessibilityEvent receivedEvent = (AccessibilityEvent) matched;
-            return mExpectedEvent.getEventType() == receivedEvent.getEventType();
-        }
-
-        public void appendTo(StringBuffer buffer) {
-            buffer.append("sendAccessibilityEvent()");
-            buffer.append(" with event type \"");
-            buffer.append(mExpectedEvent.getEventType());
-            buffer.append("\"");
-        }
-    }
-
-    /**
-     * Matcher for {@link IAccessibilityManagerClient}s.
-     */
-    private static class AnyIAccessibilityManagerClientMather implements IArgumentMatcher {
-        public boolean matches(Object matched) {
-            if (!(matched instanceof IAccessibilityManagerClient)) {
-                return false;
-            }
-            return true;
-        }
-
-        public void appendTo(StringBuffer buffer) {
-            buffer.append("addClient() with any IAccessibilityManagerClient");
-        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java b/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
index 1bc9b86..e1c5cee 100644
--- a/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
+++ b/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
@@ -62,7 +62,7 @@
      */
     public static AccessibilityServiceInfo createDefaultInfo() {
         AccessibilityServiceInfo defaultInfo = new AccessibilityServiceInfo();
-        defaultInfo.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED;
+        defaultInfo.eventTypes = AccessibilityEvent.TYPE_ANNOUNCEMENT;
         defaultInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
         defaultInfo.flags = 0;
         defaultInfo.notificationTimeout = 0;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index d8c4223..a284ca0 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -40,7 +40,7 @@
  mmma frameworks/base/services/tests/servicestests/ &&
  adb install \
    -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- adb shell am instrument -e class com.android.server.devicepolicy.DeviceOwnerTest \
+ adb shell am instrument -e class com.android.server.devicepolicy.OwnersTest \
    -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
 public class OwnersTest extends DpmTestBase {
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 0c5c557..2bfaf1b 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -185,6 +185,36 @@
             case RILConstants.NETWORK_MODE_GLOBAL:
                 raf = GSM | WCDMA | CDMA | EVDO;
                 break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
+                raf = RAF_TD_SCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
+                raf = RAF_TD_SCDMA | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
+                raf = RAF_TD_SCDMA | GSM;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                raf = RAF_LTE | RAF_TD_SCDMA | GSM;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                raf = RAF_TD_SCDMA | GSM | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA | GSM | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                raf = RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+                break;
+            case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                raf = RAF_LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+                break;
             default:
                 raf = RAF_UNKNOWN;
                 break;
@@ -248,6 +278,36 @@
             case (GSM | WCDMA | CDMA | EVDO):
                 type = RILConstants.NETWORK_MODE_GLOBAL;
                 break;
+            case RAF_TD_SCDMA:
+                type = RILConstants.NETWORK_MODE_TDSCDMA_ONLY;
+                break;
+            case (RAF_TD_SCDMA | WCDMA):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA;
+                break;
+            case (RAF_TD_SCDMA | GSM):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_GSM;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | GSM):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
+                break;
+            case (RAF_TD_SCDMA | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
+                break;
+            case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+                break;
+            case (RAF_LTE | RAF_TD_SCDMA | RAF_LTE | CDMA | EVDO | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+                break;
             default:
                 type = RILConstants.PREFERRED_NETWORK_MODE ;
                 break;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 80515cf..1337487 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -731,6 +731,9 @@
             case RIL_RADIO_TECHNOLOGY_IWLAN:
                 rtString = "IWLAN";
                 break;
+            case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+                rtString = "TD-SCDMA";
+                break;
             default:
                 rtString = "Unexpected";
                 Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1068,6 +1071,8 @@
             return TelephonyManager.NETWORK_TYPE_HSPAP;
         case ServiceState.RIL_RADIO_TECHNOLOGY_GSM:
             return TelephonyManager.NETWORK_TYPE_GSM;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+            return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
         case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN:
             return TelephonyManager.NETWORK_TYPE_IWLAN;
         default:
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index f02d109..f535e5d 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -68,6 +68,7 @@
     private int mLteRsrq;
     private int mLteRssnr;
     private int mLteCqi;
+    private int mTdScdmaRscp;
 
     private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
 
@@ -107,6 +108,7 @@
         mLteRsrq = INVALID;
         mLteRssnr = INVALID;
         mLteCqi = INVALID;
+        mTdScdmaRscp = INVALID;
         isGsm = true;
     }
 
@@ -131,6 +133,7 @@
         mLteRsrq = INVALID;
         mLteRssnr = INVALID;
         mLteCqi = INVALID;
+        mTdScdmaRscp = INVALID;
         isGsm = gsmFlag;
     }
 
@@ -143,6 +146,22 @@
             int cdmaDbm, int cdmaEcio,
             int evdoDbm, int evdoEcio, int evdoSnr,
             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
+            int tdScdmaRscp, boolean gsmFlag) {
+        initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
+                evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
+                lteRsrq, lteRssnr, lteCqi, gsmFlag);
+        mTdScdmaRscp = tdScdmaRscp;
+    }
+
+    /**
+     * Constructor
+     *
+     * @hide
+     */
+    public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+            int cdmaDbm, int cdmaEcio,
+            int evdoDbm, int evdoEcio, int evdoSnr,
+            int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
             boolean gsmFlag) {
         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
@@ -233,6 +252,7 @@
         mLteRsrq = lteRsrq;
         mLteRssnr = lteRssnr;
         mLteCqi = lteCqi;
+        mTdScdmaRscp = INVALID;
         isGsm = gsm;
         if (DBG) log("initialize: " + toString());
     }
@@ -253,6 +273,7 @@
         mLteRsrq = s.mLteRsrq;
         mLteRssnr = s.mLteRssnr;
         mLteCqi = s.mLteCqi;
+        mTdScdmaRscp = s.mTdScdmaRscp;
         isGsm = s.isGsm;
     }
 
@@ -276,6 +297,7 @@
         mLteRsrq = in.readInt();
         mLteRssnr = in.readInt();
         mLteCqi = in.readInt();
+        mTdScdmaRscp = in.readInt();
         isGsm = (in.readInt() != 0);
     }
 
@@ -302,7 +324,7 @@
         ss.mLteRsrq = in.readInt();
         ss.mLteRssnr = in.readInt();
         ss.mLteCqi = in.readInt();
-
+        ss.mTdScdmaRscp = in.readInt();
         return ss;
     }
 
@@ -322,6 +344,7 @@
         out.writeInt(mLteRsrq);
         out.writeInt(mLteRssnr);
         out.writeInt(mLteCqi);
+        out.writeInt(mTdScdmaRscp);
         out.writeInt(isGsm ? 1 : 0);
     }
 
@@ -377,6 +400,9 @@
         mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
         mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
                 : SignalStrength.INVALID;
+
+        mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120))
+                ? -mTdScdmaRscp : SignalStrength.INVALID;
         // Cqi no change
         if (DBG) log("Signal after validate=" + this);
     }
@@ -477,12 +503,15 @@
      *     while 4 represents a very strong signal strength.
      */
     public int getLevel() {
-        int level;
+        int level = 0;
 
         if (isGsm) {
             level = getLteLevel();
             if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                level = getGsmLevel();
+                level = getTdScdmaLevel();
+                if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    level = getGsmLevel();
+                }
             }
         } else {
             int cdmaLevel = getCdmaLevel();
@@ -508,10 +537,14 @@
      * @hide
      */
     public int getAsuLevel() {
-        int asuLevel;
+        int asuLevel = 0;
         if (isGsm) {
             if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                asuLevel = getGsmAsuLevel();
+                if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    asuLevel = getGsmAsuLevel();
+                } else {
+                    asuLevel = getTdScdmaAsuLevel();
+                }
             } else {
                 asuLevel = getLteAsuLevel();
             }
@@ -539,12 +572,16 @@
      * @hide
      */
     public int getDbm() {
-        int dBm;
+        int dBm = INVALID;
 
         if(isGsm()) {
             dBm = getLteDbm();
             if (dBm == INVALID) {
-                dBm = getGsmDbm();
+                if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    dBm = getGsmDbm();
+                } else {
+                    dBm = getTdScdmaDbm();
+                }
             }
         } else {
             int cdmaDbm = getCdmaDbm();
@@ -849,6 +886,54 @@
     }
 
     /**
+     * @return get TD_SCDMA dbm
+     *
+     * @hide
+     */
+    public int getTdScdmaDbm() {
+        return this.mTdScdmaRscp;
+    }
+
+    /**
+     * Get TD-SCDMA as level 0..4
+     * Range : 25 to 120
+     * INT_MAX: 0x7FFFFFFF denotes invalid value
+     * Reference: 3GPP TS 25.123, section 9.1.1.1
+     *
+     * @hide
+     */
+    public int getTdScdmaLevel() {
+        final int tdScdmaDbm = getTdScdmaDbm();
+        int level;
+
+        if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
+                level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
+        else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
+        else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
+        else if (tdScdmaDbm >= -120) level = SIGNAL_STRENGTH_POOR;
+        else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+        if (DBG) log("getTdScdmaLevel = " + level);
+        return level;
+     }
+
+    /**
+     * Get the TD-SCDMA signal level as an asu value.
+     *
+     * @hide
+     */
+    public int getTdScdmaAsuLevel() {
+        final int tdScdmaDbm = getTdScdmaDbm();
+        int tdScdmaAsuLevel;
+
+        if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
+        else tdScdmaAsuLevel = tdScdmaDbm + 120;
+        if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
+        return tdScdmaAsuLevel;
+    }
+
+   /**
      * @return hash code
      */
     @Override
@@ -860,7 +945,7 @@
                 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
                 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
                 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
-                + (isGsm ? 1 : 0));
+                + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
     }
 
     /**
@@ -892,6 +977,7 @@
                 && mLteRsrq == s.mLteRsrq
                 && mLteRssnr == s.mLteRssnr
                 && mLteCqi == s.mLteCqi
+                && mTdScdmaRscp == s.mTdScdmaRscp
                 && isGsm == s.isGsm);
     }
 
@@ -913,6 +999,7 @@
                 + " " + mLteRsrq
                 + " " + mLteRssnr
                 + " " + mLteCqi
+                + " " + mTdScdmaRscp
                 + " " + (isGsm ? "gsm|lte" : "cdma"));
     }
 
@@ -935,6 +1022,7 @@
         mLteRsrq = m.getInt("LteRsrq");
         mLteRssnr = m.getInt("LteRssnr");
         mLteCqi = m.getInt("LteCqi");
+        mTdScdmaRscp = m.getInt("TdScdma");
         isGsm = m.getBoolean("isGsm");
     }
 
@@ -957,6 +1045,7 @@
         m.putInt("LteRsrq", mLteRsrq);
         m.putInt("LteRssnr", mLteRssnr);
         m.putInt("LteCqi", mLteCqi);
+        m.putInt("TdScdma", mTdScdmaRscp);
         m.putBoolean("isGsm", Boolean.valueOf(isGsm));
     }
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e104b38..f6e4bed 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1099,11 +1099,21 @@
         case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
         case RILConstants.NETWORK_MODE_LTE_WCDMA:
         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
+        case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
+        case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
+        case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_GSM;
 
         // Use CDMA Phone for the global mode including CDMA
         case RILConstants.NETWORK_MODE_GLOBAL:
         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
+        case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_CDMA;
 
         case RILConstants.NETWORK_MODE_LTE_ONLY:
diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
index a6a2658..23a69d1 100644
--- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
@@ -71,7 +71,7 @@
      * @param disabledFeatures features disabled as defined in com.android.ims.ImsConfig#FeatureConstants.
      */
     void registrationFeatureCapabilityChanged(int serviceClass,
-            out int[] enabledFeatures, out int[] disabledFeatures);
+            in int[] enabledFeatures, in int[] disabledFeatures);
 
     /**
      * Updates the application with the waiting voice message count.
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 8d48c86..7088be8 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -96,6 +96,16 @@
     int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
     int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
     int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
+    int NETWORK_MODE_TDSCDMA_ONLY            = 13; /* TD-SCDMA only */
+    int NETWORK_MODE_TDSCDMA_WCDMA           = 14; /* TD-SCDMA and WCDMA */
+    int NETWORK_MODE_LTE_TDSCDMA             = 15; /* TD-SCDMA and LTE */
+    int NETWORK_MODE_TDSCDMA_GSM             = 16; /* TD-SCDMA and GSM */
+    int NETWORK_MODE_LTE_TDSCDMA_GSM         = 17; /* TD-SCDMA,GSM and LTE */
+    int NETWORK_MODE_TDSCDMA_GSM_WCDMA       = 18; /* TD-SCDMA, GSM/WCDMA */
+    int NETWORK_MODE_LTE_TDSCDMA_WCDMA       = 19; /* TD-SCDMA, WCDMA and LTE */
+    int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA   = 20; /* TD-SCDMA, GSM/WCDMA and LTE */
+    int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA  = 21; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+    int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
     int PREFERRED_NETWORK_MODE      = SystemProperties.getInt("ro.telephony.default_network",
             NETWORK_MODE_WCDMA_PREF);
 
diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk
index 8e6189f..d11264e 100644
--- a/tools/aidl/Android.mk
+++ b/tools/aidl/Android.mk
@@ -10,6 +10,7 @@
 # Logic shared between aidl and its unittests
 include $(CLEAR_VARS)
 LOCAL_MODULE := libaidl-common
+LOCAL_MODULE_HOST_OS := darwin linux windows
 
 LOCAL_CLANG_CFLAGS := -Wall -Werror
 # Tragically, the code is riddled with unused parameters.