Merge "Remove dock divider surface when it's not visible."
diff --git a/api/current.txt b/api/current.txt
index aea7f67..73962f8f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13880,7 +13880,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Byte> REQUEST_PIPELINE_DEPTH;
     field public static final android.hardware.camera2.CaptureResult.Key<android.graphics.Rect> SCALER_CROP_REGION;
-    field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.BlackLevelPattern> SENSOR_DYNAMIC_BLACK_LEVEL;
+    field public static final android.hardware.camera2.CaptureResult.Key<float[]> SENSOR_DYNAMIC_BLACK_LEVEL;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> SENSOR_DYNAMIC_WHITE_LEVEL;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_FRAME_DURATION;
@@ -31403,7 +31403,10 @@
   public static final class Telephony.Sms.Intents {
     method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
     field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String ACTION_DEFAULT_SMS_PACKAGE_CHANGED = "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";
+    field public static final java.lang.String ACTION_EXTERNAL_PROVIDER_CHANGE = "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
     field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+    field public static final java.lang.String EXTRA_IS_DEFAULT_SMS_APP = "android.provider.extra.IS_DEFAULT_SMS_APP";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
     field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
     field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index a8b054a..c4d99b8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -14228,7 +14228,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Byte> REQUEST_PIPELINE_DEPTH;
     field public static final android.hardware.camera2.CaptureResult.Key<android.graphics.Rect> SCALER_CROP_REGION;
-    field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.BlackLevelPattern> SENSOR_DYNAMIC_BLACK_LEVEL;
+    field public static final android.hardware.camera2.CaptureResult.Key<float[]> SENSOR_DYNAMIC_BLACK_LEVEL;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> SENSOR_DYNAMIC_WHITE_LEVEL;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_FRAME_DURATION;
@@ -33519,7 +33519,10 @@
   public static final class Telephony.Sms.Intents {
     method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
     field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String ACTION_DEFAULT_SMS_PACKAGE_CHANGED = "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";
+    field public static final java.lang.String ACTION_EXTERNAL_PROVIDER_CHANGE = "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
     field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+    field public static final java.lang.String EXTRA_IS_DEFAULT_SMS_APP = "android.provider.extra.IS_DEFAULT_SMS_APP";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
     field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
     field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
diff --git a/api/test-current.txt b/api/test-current.txt
index aea7f67..73962f8f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -13880,7 +13880,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Byte> REQUEST_PIPELINE_DEPTH;
     field public static final android.hardware.camera2.CaptureResult.Key<android.graphics.Rect> SCALER_CROP_REGION;
-    field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.BlackLevelPattern> SENSOR_DYNAMIC_BLACK_LEVEL;
+    field public static final android.hardware.camera2.CaptureResult.Key<float[]> SENSOR_DYNAMIC_BLACK_LEVEL;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> SENSOR_DYNAMIC_WHITE_LEVEL;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_EXPOSURE_TIME;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Long> SENSOR_FRAME_DURATION;
@@ -31403,7 +31403,10 @@
   public static final class Telephony.Sms.Intents {
     method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
     field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String ACTION_DEFAULT_SMS_PACKAGE_CHANGED = "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";
+    field public static final java.lang.String ACTION_EXTERNAL_PROVIDER_CHANGE = "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
     field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+    field public static final java.lang.String EXTRA_IS_DEFAULT_SMS_APP = "android.provider.extra.IS_DEFAULT_SMS_APP";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
     field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
     field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 273483a..468c145 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -178,15 +178,8 @@
  * </p>
  * <h3>Notification strategy</h3>
  * <p>
- * For each feedback type only one accessibility service is notified. Services are notified
- * in the order of registration. Hence, if two services are registered for the same
- * feedback type in the same package the first one wins. It is possible however, to
- * register a service as the default one for a given feedback type. In such a case this
- * service is invoked if no other service was interested in the event. In other words, default
- * services do not compete with other services and are notified last regardless of the
- * registration order. This enables "generic" accessibility services that work reasonably
- * well with most applications to coexist with "polished" ones that are targeted for
- * specific applications.
+ * All accessibility services are notified of all events they have requested, regardless of their
+ * feedback type.
  * </p>
  * <p class="note">
  * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 2e05edb..1370000 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -129,8 +129,8 @@
         String libname = "main";
         String funcname = "ANativeActivity_onCreate";
         ActivityInfo ai;
-        
-        mIMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+
+        mIMM = getSystemService(InputMethodManager.class);
 
         getWindow().takeSurface(this);
         getWindow().takeInputQueue(this);
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index fa11221..9c18df8 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -505,8 +505,7 @@
 
         // We made sure the IME was displayed, so also make sure it is closed
         // when we go away.
-        InputMethodManager imm = (InputMethodManager)getContext()
-                .getSystemService(Context.INPUT_METHOD_SERVICE);
+        InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
         if (imm != null) {
             imm.hideSoftInputFromWindow(
                     getWindow().getDecorView().getWindowToken(), 0);
@@ -643,8 +642,7 @@
     public void onBackPressed() {
         // If the input method is covering the search dialog completely,
         // e.g. in landscape mode with no hard keyboard, dismiss just the input method
-        InputMethodManager imm = (InputMethodManager)getContext()
-                .getSystemService(Context.INPUT_METHOD_SERVICE);
+        InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
         if (imm != null && imm.isFullscreenMode() &&
                 imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0)) {
             return;
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 5f27bca..3c2d503 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -3329,8 +3329,8 @@
      * @see CaptureRequest#SENSOR_SENSITIVITY
      */
     @PublicKey
-    public static final Key<android.hardware.camera2.params.BlackLevelPattern> SENSOR_DYNAMIC_BLACK_LEVEL =
-            new Key<android.hardware.camera2.params.BlackLevelPattern>("android.sensor.dynamicBlackLevel", android.hardware.camera2.params.BlackLevelPattern.class);
+    public static final Key<float[]> SENSOR_DYNAMIC_BLACK_LEVEL =
+            new Key<float[]>("android.sensor.dynamicBlackLevel", float[].class);
 
     /**
      * <p>Maximum raw value output by sensor for this frame.</p>
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 10307e4..515e9a2 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1028,13 +1028,25 @@
      * Guess what the network request was trying to say so that the resulting
      * network is accessible via the legacy (deprecated) API such as
      * requestRouteToHost.
-     * This means we should try to be fairly preceise about transport and
+     *
+     * This means we should try to be fairly precise about transport and
      * capability but ignore things such as networkSpecifier.
      * If the request has more than one transport or capability it doesn't
      * match the old legacy requests (they selected only single transport/capability)
      * so this function cannot map the request to a single legacy type and
      * the resulting network will not be available to the legacy APIs.
      *
+     * This code is only called from the requestNetwork API (L and above).
+     *
+     * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive
+     * because they wake up lots of apps - see http://b/23350688 . So we currently only
+     * do this for SUPL requests, which are the only ones that we know need it. If
+     * omitting these broadcasts causes unacceptable app breakage, then for backwards
+     * compatibility we can send them:
+     *
+     * if (targetSdkVersion < Build.VERSION_CODES.M) &&        // legacy API unsupported >= M
+     *     targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP))  // requestNetwork not present < L
+     *
      * TODO - This should be removed when the legacy APIs are removed.
      */
     private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
@@ -1046,6 +1058,14 @@
             return TYPE_NONE;
         }
 
+        // Do this only for SUPL, until GpsLocationProvider is fixed. http://b/25876485 .
+        if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
+            // NOTE: if this causes app breakage, we should not just comment out this early return;
+            // instead, we should make this early return conditional on the requesting app's target
+            // SDK version, as described in the comment above.
+            return TYPE_NONE;
+        }
+
         String type = null;
         int result = TYPE_NONE;
 
@@ -1062,7 +1082,7 @@
             type = "enableDUN";
             result = TYPE_MOBILE_DUN;
         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
-           type = "enableSUPL";
+            type = "enableSUPL";
             result = TYPE_MOBILE_SUPL;
         // back out this hack for mms as they no longer need this and it's causing
         // device slowdowns - b/23350688 (note, supl still needs this)
@@ -2541,7 +2561,7 @@
      * This function behaves identically to the non-timedout version, but if a suitable
      * network is not found within the given time (in milliseconds) the
      * {@link NetworkCallback#unavailable} callback is called.  The request must
-     * still be released normally by calling {@link releaseNetworkRequest}.
+     * still be released normally by calling {@link unregisterNetworkCallback}.
      *
      * <p>This method requires the caller to hold either the
      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f560f8a..c92382a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4420,8 +4420,19 @@
          * to receive changes in this value.
          */
         public static final String LOCATION_MODE = "location_mode";
+        /**
+         * Stores the previous location mode when {@link #LOCATION_MODE} is set to
+         * {@link #LOCATION_MODE_OFF}
+         * @hide
+         */
+        public static final String LOCATION_PREVIOUS_MODE = "location_previous_mode";
 
         /**
+         * Sets all location providers to the previous states before location was turned off.
+         * @hide
+         */
+        public static final int LOCATION_MODE_PREVIOUS = -1;
+        /**
          * Location access disabled.
          */
         public static final int LOCATION_MODE_OFF = 0;
@@ -5795,6 +5806,7 @@
             CLONE_TO_MANAGED_PROFILE.add(ENABLED_ACCESSIBILITY_SERVICES);
             CLONE_TO_MANAGED_PROFILE.add(ENABLED_INPUT_METHODS);
             CLONE_TO_MANAGED_PROFILE.add(LOCATION_MODE);
+            CLONE_TO_MANAGED_PROFILE.add(LOCATION_PREVIOUS_MODE);
             CLONE_TO_MANAGED_PROFILE.add(LOCATION_PROVIDERS_ALLOWED);
             CLONE_TO_MANAGED_PROFILE.add(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
             CLONE_TO_MANAGED_PROFILE.add(SELECTED_INPUT_METHOD_SUBTYPE);
@@ -5882,6 +5894,28 @@
         }
 
         /**
+         * Saves the current location mode into {@link #LOCATION_PREVIOUS_MODE}.
+         */
+        private static final boolean saveLocationModeForUser(ContentResolver cr, int userId) {
+            final int mode = getLocationModeForUser(cr, userId);
+            return putIntForUser(cr, Settings.Secure.LOCATION_PREVIOUS_MODE, mode, userId);
+        }
+
+        /**
+         * Restores the current location mode from {@link #LOCATION_PREVIOUS_MODE}.
+         */
+        private static final boolean restoreLocationModeForUser(ContentResolver cr, int userId) {
+            int mode = getIntForUser(cr, Settings.Secure.LOCATION_PREVIOUS_MODE,
+                    LOCATION_MODE_HIGH_ACCURACY, userId);
+            // Make sure that the previous mode is never "off". Otherwise the user won't be able to
+            // turn on location any longer.
+            if (mode == LOCATION_MODE_OFF) {
+                mode = LOCATION_MODE_HIGH_ACCURACY;
+            }
+            return setLocationModeForUser(cr, mode, userId);
+        }
+
+        /**
          * Thread-safe method for setting the location mode to one of
          * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY},
          * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}.
@@ -5899,7 +5933,11 @@
                 boolean gps = false;
                 boolean network = false;
                 switch (mode) {
+                    case LOCATION_MODE_PREVIOUS:
+                        // Retrieve the actual mode and set to that mode.
+                        return restoreLocationModeForUser(cr, userId);
                     case LOCATION_MODE_OFF:
+                        saveLocationModeForUser(cr, userId);
                         break;
                     case LOCATION_MODE_SENSORS_ONLY:
                         gps = true;
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index 1973ef1..9167a90 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -47,9 +47,6 @@
                 Set<X509Certificate> certificates = new ArraySet<>(mKeyStore.size());
                 for (Enumeration<String> en = mKeyStore.aliases(); en.hasMoreElements();) {
                     String alias = en.nextElement();
-                    if (!mKeyStore.isCertificateEntry(alias)) {
-                        continue;
-                    }
                     X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias);
                     if (cert != null) {
                         certificates.add(cert);
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index 2b882d3..c7a4ccc 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -15,6 +15,7 @@
  */
 package android.speech.tts;
 
+import android.annotation.NonNull;
 import android.media.AudioFormat;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
 import android.util.Log;
@@ -46,7 +47,6 @@
     private FileChannel mFileChannel;
 
     private final UtteranceProgressDispatcher mDispatcher;
-    private final Object mCallerIdentity;
 
     private boolean mStarted = false;
     private boolean mDone = false;
@@ -54,12 +54,11 @@
     /** Status code of synthesis */
     protected int mStatusCode;
 
-    FileSynthesisCallback(FileChannel fileChannel, UtteranceProgressDispatcher dispatcher,
-            Object callerIdentity, boolean clientIsUsingV2) {
+    FileSynthesisCallback(@NonNull FileChannel fileChannel,
+            @NonNull UtteranceProgressDispatcher dispatcher, boolean clientIsUsingV2) {
         super(clientIsUsingV2);
         mFileChannel = fileChannel;
         mDispatcher = dispatcher;
-        mCallerIdentity = callerIdentity;
         mStatusCode = TextToSpeech.SUCCESS;
     }
 
@@ -75,9 +74,7 @@
 
             mStatusCode = TextToSpeech.STOPPED;
             cleanUp();
-            if (mDispatcher != null) {
-                mDispatcher.dispatchOnStop();
-            }
+            mDispatcher.dispatchOnStop();
         }
     }
 
@@ -134,9 +131,7 @@
             mAudioFormat = audioFormat;
             mChannelCount = channelCount;
 
-            if (mDispatcher != null) {
-                mDispatcher.dispatchOnStart();
-            }
+            mDispatcher.dispatchOnStart();
             fileChannel = mFileChannel;
         }
 
@@ -214,8 +209,7 @@
                 if (DBG) Log.d(TAG, "Request has been aborted.");
                 return errorCodeOnStop();
             }
-            if (mDispatcher != null && mStatusCode != TextToSpeech.SUCCESS &&
-                    mStatusCode != TextToSpeech.STOPPED) {
+            if (mStatusCode != TextToSpeech.SUCCESS && mStatusCode != TextToSpeech.STOPPED) {
                 mDispatcher.dispatchOnError(mStatusCode);
                 return TextToSpeech.ERROR;
             }
@@ -239,9 +233,7 @@
 
             synchronized (mStateLock) {
                 closeFile();
-                if (mDispatcher != null) {
-                    mDispatcher.dispatchOnSuccess();
-                }
+                mDispatcher.dispatchOnSuccess();
                 return TextToSpeech.SUCCESS;
             }
         } catch (IOException ex) {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index c3aed75..8c355d8 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -1032,8 +1032,7 @@
 
         @Override
         protected AbstractSynthesisCallback createSynthesisCallback() {
-            return new FileSynthesisCallback(mFileOutputStream.getChannel(),
-                    this, getCallerIdentity(), false);
+            return new FileSynthesisCallback(mFileOutputStream.getChannel(), this, false);
         }
 
         @Override
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ab1943c..692fa66 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -22369,7 +22369,13 @@
          * Used to track views that need (at least) a partial relayout at their current size
          * during the next traversal.
          */
-        final List<View> mPartialLayoutViews = new ArrayList<View>();
+        List<View> mPartialLayoutViews = new ArrayList<>();
+
+        /**
+         * Swapped with mPartialLayoutViews during layout to avoid concurrent
+         * modification. Lazily assigned during ViewRootImpl layout.
+         */
+        List<View> mEmptyPartialLayoutViews;
 
         /**
          * Used to track the identity of the current drag operation.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b503e12..3c9310d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1974,6 +1974,15 @@
         final List<View> partialLayoutViews = mAttachInfo.mPartialLayoutViews;
         final boolean didPartialLayout;
         if (!partialLayoutViews.isEmpty()) {
+            // Measurement or layout of views may result in changes to the list
+            // of partial-layout views. Swap in an "empty" list to prevent
+            // concurrent modification of the list being traversed.
+            if (mAttachInfo.mEmptyPartialLayoutViews == null) {
+                mAttachInfo.mPartialLayoutViews = new ArrayList<>();
+            } else {
+                mAttachInfo.mPartialLayoutViews = mAttachInfo.mEmptyPartialLayoutViews;
+            }
+
             final int count = partialLayoutViews.size();
             mInLayout = true;
             for (int i = 0; i < count; i++) {
@@ -1992,9 +2001,12 @@
                 }
             }
             mInLayout = false;
-            partialLayoutViews.clear();
             didPartialLayout = true;
             triggerGlobalLayoutListener = true;
+
+            // The traversal list becomes the new empty list.
+            partialLayoutViews.clear();
+            mAttachInfo.mEmptyPartialLayoutViews = partialLayoutViews;
         } else {
             didPartialLayout = false;
         }
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index b3b95f8..f313893 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -61,8 +61,7 @@
         setText("");
         mMatches = (TextView) mCustomView.findViewById(
                 com.android.internal.R.id.matches);
-        mInput = (InputMethodManager)
-                context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        mInput = context.getSystemService(InputMethodManager.class);
         mResources = context.getResources();
     }
 
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 90de053..f050e49 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5755,8 +5755,8 @@
             // The editor is off in its own window; we need to be
             // the one that does this.
             if (editorAction == EditorInfo.IME_ACTION_DONE) {
-                InputMethodManager imm = (InputMethodManager)
-                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                InputMethodManager imm =
+                        getContext().getSystemService(InputMethodManager.class);
                 if (imm != null) {
                     imm.hideSoftInputFromWindow(getWindowToken(), 0);
                 }
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index ad2b4a7..88f02d1 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -152,8 +152,7 @@
      */
     private Runnable mShowImeRunnable = new Runnable() {
         public void run() {
-            InputMethodManager imm = (InputMethodManager)
-                    getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+            InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
 
             if (imm != null) {
                 imm.showSoftInputUnchecked(0, null);
@@ -912,8 +911,7 @@
             post(mShowImeRunnable);
         } else {
             removeCallbacks(mShowImeRunnable);
-            InputMethodManager imm = (InputMethodManager)
-                    getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+            InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
 
             if (imm != null) {
                 imm.hideSoftInputFromWindow(getWindowToken(), 0);
@@ -1768,8 +1766,8 @@
             super.onWindowFocusChanged(hasWindowFocus);
 
             if (hasWindowFocus && mSearchView.hasFocus() && getVisibility() == VISIBLE) {
-                InputMethodManager inputManager = (InputMethodManager) getContext()
-                        .getSystemService(Context.INPUT_METHOD_SERVICE);
+                InputMethodManager inputManager =
+                        getContext().getSystemService(InputMethodManager.class);
                 inputManager.showSoftInput(this, 0);
                 // If in landscape mode, then make sure that
                 // the ime is in front of the dropdown.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 476c6a2..2f385c1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7225,6 +7225,7 @@
         // of the intended optimizations as part of requestLayoutForChild.
         nullLayouts();
         requestLayout();
+        invalidate();
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index e339c44..592576b 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -137,7 +137,7 @@
         super(c);
         setFocusableInTouchMode(true);
 
-        mIm = (InputManager)c.getSystemService(Context.INPUT_SERVICE);
+        mIm = c.getSystemService(InputManager.class);
 
         mVC = ViewConfiguration.get(c);
         mTextPaint = new Paint();
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4a9b163..9be3bfb 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1470,8 +1470,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"المطالبة برقم التعريف الشخصي قبل إزالة التثبيت"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"المطالبة بنقش إلغاء القفل قبل إزالة التثبيت"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"المطالبة بكلمة المرور قبل إزالة التثبيت"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"التطبيق غير قابل لتغيير الحجم، يمكنك تمريره بإصبعين."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"تم تثبيت الحزمة عن طريق المشرف"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"تم التحديث بواسطة المشرف"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"تم حذف الحزمة عن طريق المشرف"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 233d709..2617bdb 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Запитване за ПИН код преди освобождаване"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запитване за фигура за отключване преди освобождаване"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитване за парола преди освобождаване"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Приложението не може да се преоразмерява. Превъртете го с два пръста."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирано от администратора ви"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Актуализирано от администратора ви"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Изтрито от администратора ви"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 646f734..dbf85e3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Bed om pinkode inden frigørelse"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bed om oplåsningsmønster ved deaktivering"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bed om adgangskode inden frigørelse"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Appens størrelse kan ikke ændres. Gennemgå den ved at rulle med to fingre."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Installeret af din administrator"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Opdateret af administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet af din administrator"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 7a7cce1..e00fbec 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Να γίνεται ερώτηση για το PIN, πριν από το ξεκαρφίτσωμα"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Το μέγεθος της εφαρμογής δεν είναι προσαρμόσιμο. Σύρετε προς τα κάτω με δύο δάχτυλα."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Εγκαταστάθηκε από το διαχειριστή σας"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ενημερώθηκε από το διαχειριστή σας"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Διαγράφηκε από το διαχειριστή σας"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 0168d4f..19f1bd9 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar PIN para quitar fijación"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar patrón de desbloqueo para quitar fijación"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para quitar fijación"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"No se puede modificar el tamaño de la app, desplázala con dos dedos."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Lo instaló el administrador."</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado por el administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Lo eliminó el administrador."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 04cdfe0..f290c04 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar PIN para desactivar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar patrón de desbloqueo para desactivar"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para desactivar"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"No se puede cambiar el tamaño de la aplicación: desplázala con dos dedos."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado por tu administrador"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado por tu administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado por tu administrador"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 5898ca0..ca6ad3c 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Enne vabastamist küsi PIN-koodi"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Enne vabastamist küsi avamismustrit"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Enne vabastamist küsi parooli"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Rakenduse suurust ei saa muuta. Kerige kahe sõrmega."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Installis teie administraator"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Värskendas administraator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Kustutas teie administraator"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 689e9e0..bc5caa2 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -191,7 +191,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"آماده‌سازی برای به‌روزرسانی…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"در حال پردازش بسته‌بندی به‌روز…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"در حال راه‌اندازی مجدد…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"بازنشانی به داده‌های کارخانه"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"بازنشانی داده‌های کارخانه"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"در حال راه‌اندازی مجدد…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"در حال خاموش شدن…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"رایانهٔ لوحی شما خاموش می‌شود."</string>
@@ -511,9 +511,9 @@
     <string name="policylab_forceLock" msgid="2274085384704248431">"قفل کردن صفحه"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"نحوه و زمان قفل شدن صفحه را کنترل می‌کند."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"پاک کردن تمام داده‌ها"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"با انجام بازنشانی به داده‌های کارخانه، داده‌های رایانهٔ لوحی بدون هشدار پاک می‌شود."</string>
-    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"داده‌های تلویزیون را بدون هشدار با انجام بازنشانی به داده کارخانه پاک کنید."</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"با انجام بازنشانی به داده‌های کارخانه، داده‌های تلفن بدون هشدار پاک می‌شود."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"با انجام بازنشانی داده‌های کارخانه، داده‌های رایانهٔ لوحی بدون هشدار پاک می‌شود."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"داده‌های تلویزیون را بدون هشدار با انجام بازنشانی داده‌های کارخانه پاک کنید."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"با انجام بازنشانی داده‌های کارخانه، داده‌های تلفن بدون هشدار پاک می‌شود."</string>
     <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"پاک کردن داده‌های کاربر"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"داده‌های این کاربر را در این رایانه لوحی بدون هشدار پاک می‌کند."</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"داده‌های این کاربر را در این تلویزیون بدون هشدار پاک می‌کند."</string>
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"درخواست کد پین قبل از برداشتن پین"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"درخواست الگوی باز کردن قفل قبل از برداشتن پین"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"درخواست گذرواژه قبل از برداشتن پین"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"اندازه برنامه قابل تغییر نیست، با دو انگشت آن را پیمایش کنید."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"توسط سرپرستتان نصب شد"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"توسط سرپرست شما به‌روزرسانی شد"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"توسط سرپرستتان حذف شد"</string>
@@ -1484,7 +1483,7 @@
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"آخر هفته"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"رویداد"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> آن را بی‌صدا کرد"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی به داده کارخانه انجام نگیرد، بی‌ثبات بماند."</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی داده‌های کارخانه انجام نگیرد، بی‌ثبات بماند."</string>
     <string name="system_error_manufacturer" msgid="8086872414744210668">"دستگاهتان یک مشکل داخلی دارد. برای جزئیات آن با سازنده‌تان تماس بگیرید."</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"‏درخواست USSD به درخواست DIAL اصلاح می‌شود."</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"‏درخواست USSD به درخواست SS اصلاح می‌شود."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8af6e56..3494d53 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pyydä PIN ennen irrotusta"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pyydä salasana ennen irrotusta"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Sovelluksen koko ei muutu. Vieritä näkymää kahdella sormella."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Järjestelmänvalvoja on asentanut paketin."</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Järjestelmänvalvojasi on päivittänyt paketin."</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Järjestelmänvalvoja on poistanut paketin."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index e2daae6..94f59fa 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Demander le NIP avant d\'annuler l\'épinglage"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Impossible de redimensionner l\'application. Faites-la défiler avec deux doigts."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Installé par votre administrateur"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Mis à jour par votre administrateur"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 5de0971..965b229 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Demander le code PIN avant d\'annuler l\'épinglage"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Il est impossible de redimensionner l\'application. Faites-la défiler avec deux doigts."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Installé par votre administrateur"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Mis à jour par votre administrateur"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index ba25f89..a5c42e3 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar un PIN antes de soltar a pantalla"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar un padrón de desbloqueo antes de soltar a pantalla"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar un contrasinal antes de soltar a pantalla"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Non se pode cambiar o tamaño da aplicación. Desprázate por ela con dous dedos."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado polo administrador"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado polo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado polo administrador"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index ce05ef5..6dabd69 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"અનપિન કરતાં પહેલાં PIN માટે પૂછો"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"અનપિન કરતા પહેલાં અનલૉક પેટર્ન માટે પૂછો"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"ઍપ્લિકેશનનું કદ બદલવા યોગ્ય નથી, બે આંગળીઓ વડે તેને સ્ક્રોલ કરો."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"તમારા વ્યવસ્થાપક દ્વારા ઇન્સ્ટોલ કરેલ"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ થયેલ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખેલ"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 9bc0267..2596f1c0 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1443,8 +1443,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN radi otkvačivanja"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje radi otkvačivanja"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži zaporku radi otkvačivanja"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Veličina aplikacije ne može se mijenjati, pomičite je s dva prsta."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurira vaš administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 02c6bed..29474f0 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ապաամրացնելուց առաջ հարցնել PIN-կոդը"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ապաամրացնելուց առաջ հարցնել ապակողպող նախշը"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ապաամրացնելուց առաջ հարցնել գաղտնաբառը"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Հավելվածի չափը հնարավոր չէ փոխել, ոլորեք այն երկու մատի օգնությամբ:"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Ադմինիստրատորը տեղադրել է այն"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ադմինիստրատորը թարմացրել է այն"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ադմինիստրատորը ջնջել է այն"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 7346d31..9a3ae05 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Meminta PIN sebelum melepas sematan"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Meminta pola pembukaan kunci sebelum melepas sematan"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Meminta sandi sebelum melepas sematan"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Aplikasi tidak dapat diubah ukurannya, gulir dengan dua jari."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Dipasang oleh administrator"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Diperbarui oleh administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Dihapus oleh administrator"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index c6ec5b1..23db2d2 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Biðja um PIN-númer til að losa"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Biðja um opnunarmynstur til að losa"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Biðja um aðgangsorð til að losa"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Ekki er hægt að breyta stærð forritsins, flettu upp og niður með tveimur fingrum."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Uppsett af kerfisstjóra"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Uppfært af kerfisstjóranum"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eytt af kerfisstjóra"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index c4ecbad..ff005ee 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Richiedi il PIN per lo sblocco"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Richiedi sequenza di sblocco prima di sbloccare"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Richiedi password prima di sbloccare"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Non è posssibile ridimensionare l\'app: scorri con due dita."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Installato dall\'amministratore"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Aggiornato dall\'amministratore"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminato dall\'amministratore"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 55fa332..06cf587 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1452,8 +1452,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"‏בקש PIN לפני ביטול הצמדה"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"בקש קו ביטול נעילה לפני ביטול הצמדה"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"בקש סיסמה לפני ביטול הצמדה"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"אין אפשרות לשנות את גודל האפליקציה, גלול אותה בשתי אצבעות."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"הותקנה על ידי מנהל המערכת שלך"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"עודכן על ידי מנהל המערכת שלך"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"נמחקה על ידי מנהל המערכת שלך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a74d5b7..807dbd3 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"オフライン再生を解除する前にPINの入力を求める"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"画面固定を解除する前にロック解除パターンの入力を求める"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"オフライン再生を解除する前にパスワードの入力を求める"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"アプリのサイズは変更できません。2 本の指でスクロールしてください。"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"管理者によってインストールされました"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"管理者によって更新されています"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"管理者によって削除されました"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index d37f6099..9ce703f 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ფიქსაციის მოხსნამდე PIN-ის მოთხოვნა"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ფიქსაციის მოხსნამდე განბლოკვის ნიმუშის მოთხოვნა"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"აპის ზომა ვერ შეიცვლება. გადაადგილდით მასში ორი თითის მეშვეობით."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"თქვენი ადმინისტრატორის მიერ დაყენებული"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"განახლებულია თქვენი ადმინისტრატორის მიერ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"თქვენი ადმინისტრატორის მიერ წაშლილი"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 0a79c3b..7b3c756 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1305,7 +1305,7 @@
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Қол жетімділік өшірілді."</string>
     <string name="user_switched" msgid="3768006783166984410">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ауысу орындалуда…"</string>
-    <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> ішінен шығу орындалуда…"</string>
+    <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> ішінен шығу…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Пайдаланушы"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Қателік"</string>
     <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Бұл өзгертуге әкімші рұқсат етпеген"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 21b1dc6..ad3b9bd 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1436,8 +1436,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"សួរ​រក​កូដ PIN មុន​ពេល​ផ្ដាច់"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"សួរ​រក​លំនាំ​ដោះ​សោ​មុន​ពេល​ផ្ដាច់"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"សួរ​រក​ពាក្យ​សម្ងាត់​មុន​ពេល​ផ្ដាច់"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"កម្មវិធីមិនអាចផ្លាស់ប្តូរទំហំបានទេ សូមរមូរវាដោយប្រើម្រាមដៃពីរ។"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"បានដំឡើងដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"បានធ្វើបច្ចុប្បន្នភាពដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"បានលុបដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 8ed4a6f..8e546ba 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"고정 해제 이전에 PIN 요청"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"고정 해제 이전에 잠금해제 패턴 요청"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"고정 해제 이전에 비밀번호 요청"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"앱에서 크기 조절이 불가능합니다. 두 손가락을 사용해 스크롤하세요."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"관리자가 설치함"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"관리자에 의해 업데이트됨"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"관리자가 삭제함"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 8381c32..55dd4ec 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1435,8 +1435,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Бошотуудан мурун PIN суралсын"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Бошотуудан мурун кулпуну ачкан үлгү суралсын"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Бошотуудан мурун сырсөз суралсын"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Колдонмонун көлөмүн өзгөртүүгө болбойт, андыктан эки манжаңыз менен сыдырып караңыз."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Администраторуңуз тарабынан орнотулган"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Администраторуңуз жаңырткан"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Администраторуңуз тарабынан жок кылынган"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 9884bf1..fa3be85 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1305,7 +1305,7 @@
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ຍົກເລີກໂຕຊ່ວຍການເຂົ້າເຖິງແລ້ວ."</string>
     <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"ກຳ​ລັງ​ສະ​ລັບ​​ໄປ​ຫາ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
-    <string name="user_logging_out_message" msgid="8939524935808875155">"ກຳລັງ​ອອກ​ຈາກ​ລະບົບ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="user_logging_out_message" msgid="8939524935808875155">"ກຳລັງອອກຈາກລະບົບ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="2716755460376028154">"ເຈົ້າຂອງ"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ຜິດພາດ"</string>
     <string name="error_message_change_not_allowed" msgid="1347282344200417578">"​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານບໍ່​ອະ​ນຸ​ຍາດ​ໃຫ້​ປ່ຽນ​ແປງ​ສິ່ງ​ນີ້"</string>
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"​ຖາມ​ຫາ PIN ກ່ອນ​ຍົກ​ເລີກ​ການປັກ​ໝຸດ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"​ຖາມ​ຫາ​ຮູບ​ແບບ​ປົດ​ລັອກ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"​ຖາມ​ຫາ​ລະ​ຫັດ​ຜ່ານ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"ບໍ່ສາມາດປັບຂະໜາດແອັບຯໄດ້, ກະລຸນາເລື່ອນມັນໂດຍໃຊ້ນິ້ວສອງນິ້ວແທນ."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"ຜູ້​ຄວບ​ຄຸມ​ຂອງ​ທ່ານ​ຕິດ​ຕັ້ງ​ໃສ່​ແລ້ວ"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"ອັບ​ເດດ​ໂດຍ​ຜູ້​ຄວບ​ຄຸມ​ຂອງ​ທ່ານ​ແລ້ວ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ຖືກ​ຜູ້​ຄວບ​ຄຸມ​ຂອງ​ທ່ານ​ລຶບ​ໄປ​ແລ້ວ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1c326fe..cfcb639 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1452,8 +1452,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Prašyti PIN kodo prieš atsegant"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Prašyti atrakinimo piešinio prieš atsegant"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Prašyti slaptažodžio prieš atsegant"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Programos dydis nekeičiamas, slinkite dviem pirštais."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Įdiegė administratorius"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atnaujino administratorius"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ištrynė administratorius"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index cd2efc4a..99d5d46 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1436,8 +1436,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Прашај за ПИН пред откачување"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Прашај за шема за отклучување пред откачување"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Прашај за лозинка пред откачување"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Не може да се промени големината на апликацијата. Движете ја со два прста."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирано од администраторот"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ажурирано од администраторот"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Избришано од администраторот"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index c8eae7e..f114cb9 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ചെയ്യുംമുമ്പ് പിൻ ചോദിക്കൂ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് അൺലോക്ക് പാറ്റേൺ ആവശ്യപ്പെടുക"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് പാസ്‌വേഡ് ആവശ്യപ്പെടുക"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"ആപ്പിന്റെ വലുപ്പം ക്രമീകരിക്കാൻ കഴിയില്ല, രണ്ട് വിരലുകൾ ഉപയോഗിച്ച് അത് സ്ക്രോൾ ചെയ്യുക."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ ഇൻസ്റ്റാളുചെയ്‌തു"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ അപ്‌ഡേറ്റുചെയ്‌തു"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ ഇല്ലാതാക്കി"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 7b7d4b1..ac226a4 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Тогтоосныг суллахаас өмнө PIN асуух"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Тогтоосныг суллахаас өмнө түгжээ тайлах хээ асуух"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Апп-н хэмжээ нь өөрчлөгддөггүй. Үүнийг 2 хуруугаараа гүйлгэнэ үү."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Таны админ суулгасан байна"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Танай админ шинэчилсэн"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Таны админ устгасан байна"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index f354ea0..d9175c2 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Minta PIN sebelum menyahsemat"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Minta corak buka kunci sebelum menyahsemat"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Minta kata laluan sebelum menyahsemat"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Apl tidak boleh tukar saiznya, tatal apl itu menggunakan dua jari."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Dipasang oleh pentadbir anda"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Dikemas kini oleh pentadbir anda"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Dipadamkan oleh pentadbir anda"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 4fc7078..f504175 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-kode for å løsne apper"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Krev bruk av opplåsningsmønster for å løsne apper"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Krev passord for å løsne apper"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Du kan ikke endre størrselse på appen – rull med to fingre."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Installert av administratoren"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Oppdatert av administratoren"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet av administratoren"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 17e67f8..7867c59 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1440,12 +1440,11 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"पिन निकाल्नुअघि PIN सोध्नुहोस्"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"पिन निकाल्नुअघि खोल्ने रूपरेखा सोध्नुहोस्"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"अनुप्रयोगको आकार सानो-ठुलो बनाउन मिल्दैन, दुई औँलाले यसलाई स्क्रोल गर्नुहोस्।"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"तपाईँको प्रशासकद्वारा स्थापना गरिएको"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"तपाईँको प्रशासकद्वारा अद्यावधिक गरिएको"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"तपाईँको प्रशासकद्वारा हटाइएको"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"ब्याट्रीको आयु सुधार्न, ब्याट्री रक्षकले तपाईँको यन्त्रको कार्यसम्पादन घटाउँछ र भाइब्रेसन, स्थान सेवा र बहुसंख्यक पृष्ठभूमि डेटा सीमित गर्दछ। इमेल, सन्देश, र अन्य अनुप्रयोगहरू जुन सिङ्कमा भर पर्छन् अद्यावधिक नहुन सक्छन् जबसम्म तपाईँ तिनीहरूलाई खोल्नुहुन्न\n\n ब्याट्री रक्षक स्वत: निस्कृय हुन्छ जब तपाईँको यन्त्र चार्ज हुँदै हुन्छ।"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"ब्याट्रीको आयु सुधार्न, ब्याट्री संरक्षकले तपाईँको यन्त्रको कार्यसम्पादन घटाउँछ र भाइब्रेसन, स्थान सेवा र बहुसंख्यक पृष्ठभूमि डेटा सीमित गर्दछ। इमेल, सन्देश, र अन्य अनुप्रयोगहरू जुन सिङ्कमा भर पर्छन् अद्यावधिक नहुन सक्छन् जबसम्म तपाईँ तिनीहरूलाई खोल्नुहुन्न\n\n ब्याट्री संरक्षक स्वत: निस्कृय हुन्छ जब तपाईँको यन्त्र चार्ज हुँदै हुन्छ।"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other"> %1$d मिनेटको लागि (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> सम्म)</item>
       <item quantity="one">एक मिनेटको लागि (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> सम्म)</item>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 14e56cb..ad826262 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1452,8 +1452,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Podaj PIN, aby odpiąć"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Aby odpiąć, poproś o wzór odblokowania"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Aby odpiąć, poproś o hasło"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Rozmiaru tej aplikacji nie można zmienić. Przewiń ją dwoma palcami."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Zainstalowany przez administratora"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Zaktualizowane przez administratora"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Usunięty przez administratora"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 8212d13..c338b3b 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de liberar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir padrão de desbloqueio antes de liberar"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"O app não é redimensionável. Desloque-o com dois dedos."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo seu administrador"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 90091d8..6b0581f 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de soltar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir sequência de desbloqueio antes de soltar"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir palavra-passe antes de soltar"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"A aplicação não é redimensionável. Desloque-a com dois dedos."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo administrador"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado pelo administrador"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 8212d13..c338b3b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de liberar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir padrão de desbloqueio antes de liberar"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"O app não é redimensionável. Desloque-o com dois dedos."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo seu administrador"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 9536c70..9e676fd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1443,8 +1443,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicită codul PIN înainte de a anula fixarea"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicită modelul pentru deblocare înainte de a anula fixarea"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicită parola înainte de a anula fixarea"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Aplicația nu poate fi redimensionată. Derulați în ea cu două degete."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalat de administrator"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizat de un administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Șters de administrator"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 613c738..ca1a986 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1452,8 +1452,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-код для отключения"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запрашивать графический ключ для отключения блокировки"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запрашивать пароль для отключения блокировки"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Размер окна нельзя изменить. Прокрутите страницу двумя пальцами."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Установлено администратором"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Обновлено администратором"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Удалено администратором"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index b9ae0e9..66061d1 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1436,8 +1436,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ගැලවීමට පෙර PIN විමසන්න"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"යෙදුම ප්‍රතිප්‍රමාණ කළ හැකි නොවේ, එය ඇඟිලි දෙකකින් අනුචලනය කරන්න."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"ඔබගේ පරිපාලක විසින් ස්ථාපනය කරන ලද"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"ඔබගේ පරිපාලක විසින් යාවත්කාලීන කරන ලදී"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ඔබගේ පරිපාලක විසින් මකන ලද"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 856f8f7..72e8db2 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1452,8 +1452,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pred uvoľnením požiadať o číslo PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred uvoľnením požiadať o heslo"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Veľkosť aplikácie nie je možné zmeniť. Zobrazenie môžete posúvať dvoma prstami."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Inštalovaný správcom"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Aktualizované správcom"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Odstránený správcom"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index eff1574..9f1c669 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1452,8 +1452,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Zahtevaj PIN pred odpenjanjem"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred odpenjanjem vprašaj za geslo"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Velikosti aplikacije ni mogoče spremeniti. Po njej se pomikajte z dvema prstoma."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Namestil skrbnik"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Posodobil skrbnik"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisal skrbnik"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index a29a960..d67a5fe 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Zhgozhdimi kërkon PIN-in"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Kërko model shkyçjeje para heqjes së gozhdimit"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Përmasa e apl. nuk mund të ndryshohet, lëvize atë me të dy gishtat."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"U instalua nga administratori yt"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Përditësuar nga administratori"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"U fshi nga administratori yt"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9d12292..ddb9ba7 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1443,8 +1443,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Тражи PIN пре откачињања"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Тражи шаблон за откључавање пре откачињања"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тражи лозинку пре откачињања"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Величина апликације не може да се мења, померајте је помоћу два прста."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирао је ваш администратор"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ажурирао је администратор"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Избрисао је ваш адмиистратор"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 57edbcb..f5172fe 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Be om pinkod innan skärmen slutar fästas"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Be om upplåsningsmönster innan skärmen slutar fästas"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Be om lösenord innan skärmen slutar fästas"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Det går inte att ändra appens storlek. Rulla med två fingrar."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Paketet har installerats av administratören"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Uppdaterat av administratören"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Paketet har raderats av administratören"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f168d6c..81bc75f 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ขอ PIN ก่อนเลิกตรึง"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ขอรูปแบบการปลดล็อกก่อนเลิกตรึง"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ขอรหัสผ่านก่อนเลิกตรึง"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"แอปไม่สามารถปรับขนาดได้ เลื่อนแอปด้วยนิ้ว 2 นิ้ว"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"ติดตั้งโดยผู้ดูแลระบบของคุณ"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"อัปเดตโดยผู้ดูแลระบบ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ลบโดยผู้ดูแลระบบของคุณ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ab30e30..29efae69 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Humingi ng PIN bago mag-unpin"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Humingi ng pattern sa pag-unlock bago mag-unpin"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Humingi ng password bago mag-unpin"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Hindi nare-resize ang app, mag-scroll dito gamit ang dalawang daliri."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Na-install ng iyong administrator"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Na-update ng iyong administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Na-delete ng iyong administrator"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8cf8935..dac5259 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sabitlemeyi kaldırmadan önce PIN\'i sor"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Uygulama yeniden boyutlandırılamaz. İki parmağınızla kaydırın."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Yöneticiniz tarafından yüklendi"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Yöneticiniz tarafından güncellendi"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Yöneticiniz tarafından silindi"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index c4d2466..388b790 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"‏پن ہٹانے سے پہلے PIN طلب کریں"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"ایپ ری سائز ایبل نہیں ہے، اسے دو انگلیوں کے ساتھ سکرول کریں۔"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"آپ کے منتظم کی جانب سے انسٹال کر دیا گیا"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"آپ کے منتظم نے اپ ڈيٹ کر دیا"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"آپ کے منتظم کی جانب سے حذف کر دیا گیا"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 596bbed..bafedfc 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Yechishda PIN-kod so‘ralsin"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bo‘shatishdan oldin chizmali parol so‘ralsin"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bo‘shatishdan oldin parol so‘ralsin"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Oyna o‘lchamini o‘zgartirib bo‘lmaydi. Sahifani ikkita barmoq bilan aylantiring."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Administratoringiz tomonidan o‘rnatilgan"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Administratoringiz tomonidan yangilandi"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratoringiz tomonidan o‘chirilgan"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c5aa37e..9165f4d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Hỏi mã PIN trước khi bỏ ghim"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Hỏi hình mở khóa trước khi bỏ ghim"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Hỏi mật khẩu trước khi bỏ ghim"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Ứng dụng không đổi kích thước được, hãy cuộn ứng dụng bằng hai ngón tay."</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"Được cài đặt bởi quản trị viên của bạn"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Được cập nhật bởi quản trị viên của bạn"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Đã bị xóa bởi quản trị viên của bạn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 311fe55..36a1a7f 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1305,8 +1305,7 @@
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消无障碍功能。"</string>
     <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
-    <!-- no translation found for user_logging_out_message (8939524935808875155) -->
-    <skip />
+    <string name="user_logging_out_message" msgid="8939524935808875155">"正在将<xliff:g id="NAME">%1$s</xliff:g>退出帐号…"</string>
     <string name="owner_name" msgid="2716755460376028154">"机主"</string>
     <string name="error_message_title" msgid="4510373083082500195">"错误"</string>
     <string name="error_message_change_not_allowed" msgid="1347282344200417578">"您的管理员不允许进行此更改"</string>
@@ -1435,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"取消时要求输入PIN码"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消时要求绘制解锁图案"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消时要求输入密码"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"无法调整这个应用的大小,请用双指滚动应用。"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理员安装"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"由您单位的管理员更新"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"已被管理员删除"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 4d23d76..e938fb8 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1434,8 +1434,7 @@
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"取消固定時必須輸入 PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖形"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
-    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
-    <skip />
+    <string name="dock_non_resizeble_text" msgid="9156251681042762723">"無法調整這個應用程式的大小,請用雙指捲動該應用程式。"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理員安裝"</string>
     <string name="package_updated_device_owner" msgid="8856631322440187071">"由您的管理員更新"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"已遭管理員刪除"</string>
diff --git a/data/sounds/AllAudio.mk b/data/sounds/AllAudio.mk
index f6d8ee9..edfd380 100644
--- a/data/sounds/AllAudio.mk
+++ b/data/sounds/AllAudio.mk
@@ -228,6 +228,7 @@
     $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
     $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \
     $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
+    $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
     $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \
     $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
     $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk
index 5a5eea6..c5222af 100644
--- a/data/sounds/AudioPackage10.mk
+++ b/data/sounds/AudioPackage10.mk
@@ -1,9 +1,9 @@
 #
 # Audio Package 10 - Mako
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -23,6 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/AudioPackage11.mk b/data/sounds/AudioPackage11.mk
index 0f85b33..43c83b9 100644
--- a/data/sounds/AudioPackage11.mk
+++ b/data/sounds/AudioPackage11.mk
@@ -1,9 +1,9 @@
 #
 # Audio Package 11 - Razor
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -23,6 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/AudioPackage12.mk b/data/sounds/AudioPackage12.mk
index 4251332..cd4d35b 100644
--- a/data/sounds/AudioPackage12.mk
+++ b/data/sounds/AudioPackage12.mk
@@ -13,7 +13,7 @@
 RINGTONE_FILES := Callisto Dione Ganymede Luna Oberon Phobos Sedna Titania Triton Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
 	camera_focus Dock Undock Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted
+MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted VideoStop
 
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
 	$(LOCAL_PATH)/alarms/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg)
diff --git a/data/sounds/AudioPackage12_48.mk b/data/sounds/AudioPackage12_48.mk
index 70e68d3..80758f4 100644
--- a/data/sounds/AudioPackage12_48.mk
+++ b/data/sounds/AudioPackage12_48.mk
@@ -13,7 +13,7 @@
 RINGTONE_FILES := Callisto Dione Ganymede Luna Oberon Phobos Sedna Titania Triton Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
 	Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted
+MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted VideoStop
 
 # Alarms not yet available in 48 kHz
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
diff --git a/data/sounds/AudioPackage13.mk b/data/sounds/AudioPackage13.mk
index cec7280..d33a4af 100644
--- a/data/sounds/AudioPackage13.mk
+++ b/data/sounds/AudioPackage13.mk
@@ -14,7 +14,7 @@
 	Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
 	camera_focus Dock Undock Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery
+MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery VideoStop
 
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
 	$(LOCAL_PATH)/alarms/material/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg)
diff --git a/data/sounds/AudioPackage13_48.mk b/data/sounds/AudioPackage13_48.mk
index d1b17c8..9c320ae 100644
--- a/data/sounds/AudioPackage13_48.mk
+++ b/data/sounds/AudioPackage13_48.mk
@@ -14,7 +14,7 @@
 	Umbriel
 EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete KeypressSpacebar KeypressStandard \
 	Lock Unlock Trusted
-MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery
+MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery VideoStop
 
 PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\
 	$(LOCAL_PATH)/alarms/material/ogg/$(fn)_48k.ogg:system/media/audio/alarms/$(fn).ogg)
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
index ba9d7e2..40319c4 100644
--- a/data/sounds/AudioPackage2.mk
+++ b/data/sounds/AudioPackage2.mk
@@ -1,11 +1,11 @@
 #
 # Audio Package 2
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
 # This is a larger package of sounds than the 1.0 release for devices
 # that have larger internal flash.
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -34,6 +34,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk
index 5bfeb42..a05de72 100644
--- a/data/sounds/AudioPackage3.mk
+++ b/data/sounds/AudioPackage3.mk
@@ -1,11 +1,11 @@
 #
 # Audio Package 3
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
 # This is a larger package of sounds than the 1.0 release for devices
 # that have larger internal flash.
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -34,6 +34,7 @@
 	$(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk
index 43dbe20..d376a2d 100644
--- a/data/sounds/AudioPackage4.mk
+++ b/data/sounds/AudioPackage4.mk
@@ -1,11 +1,11 @@
 #
 # Audio Package 4
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
 # This is a larger package of sounds than the 1.0 release for devices
 # that have larger internal flash.
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -39,6 +39,7 @@
 	$(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage5.mk b/data/sounds/AudioPackage5.mk
index fbbb16a..72384c8 100644
--- a/data/sounds/AudioPackage5.mk
+++ b/data/sounds/AudioPackage5.mk
@@ -1,9 +1,9 @@
 #
 # Audio Package 5 - Crespo/Soju
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -20,6 +20,7 @@
 	$(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/AudioPackage6.mk b/data/sounds/AudioPackage6.mk
index c843fdc..5413704 100644
--- a/data/sounds/AudioPackage6.mk
+++ b/data/sounds/AudioPackage6.mk
@@ -1,9 +1,9 @@
 #
 # Audio Package 6 - Trygon/Stingray
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -19,6 +19,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index ce82651..e4763be 100644
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -1,9 +1,9 @@
 #
 # Audio Package 7 - Tuna
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -21,6 +21,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/AudioPackage7alt.mk b/data/sounds/AudioPackage7alt.mk
index db468f3..30e6173 100644
--- a/data/sounds/AudioPackage7alt.mk
+++ b/data/sounds/AudioPackage7alt.mk
@@ -21,6 +21,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
 	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
diff --git a/data/sounds/AudioPackage8.mk b/data/sounds/AudioPackage8.mk
index 4112c18..b38e62d 100644
--- a/data/sounds/AudioPackage8.mk
+++ b/data/sounds/AudioPackage8.mk
@@ -1,9 +1,9 @@
 #
 # Audio Package 7 - Tuna
-# 
+#
 # Include this file in a product makefile to include these audio files
 #
-# 
+#
 
 LOCAL_PATH:= frameworks/base/data/sounds
 
@@ -23,6 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/AudioPackage9.mk b/data/sounds/AudioPackage9.mk
index 1b430c0..dbe1350 100644
--- a/data/sounds/AudioPackage9.mk
+++ b/data/sounds/AudioPackage9.mk
@@ -23,6 +23,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
 	$(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
diff --git a/data/sounds/OriginalAudio.mk b/data/sounds/OriginalAudio.mk
index e1ca24b..f683752 100644
--- a/data/sounds/OriginalAudio.mk
+++ b/data/sounds/OriginalAudio.mk
@@ -1,8 +1,8 @@
 #
 # Original audio package that shipped on G1
-# 
+#
 # This file is included from core.mk so that all devices will have these sounds
-# 
+#
 # TODO: Clean up for future releases
 #
 
@@ -32,6 +32,7 @@
 	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
 	$(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
 	$(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg
diff --git a/data/sounds/effects/VideoStop.ogg b/data/sounds/effects/VideoStop.ogg
new file mode 100644
index 0000000..1450522
--- /dev/null
+++ b/data/sounds/effects/VideoStop.ogg
Binary files differ
diff --git a/data/sounds/effects/VideoStop.wav b/data/sounds/effects/VideoStop.wav
new file mode 100644
index 0000000..5809d93
--- /dev/null
+++ b/data/sounds/effects/VideoStop.wav
Binary files differ
diff --git a/data/sounds/effects/material/ogg/VideoStop.ogg b/data/sounds/effects/material/ogg/VideoStop.ogg
new file mode 100644
index 0000000..e98fabc0
--- /dev/null
+++ b/data/sounds/effects/material/ogg/VideoStop.ogg
Binary files differ
diff --git a/data/sounds/effects/material/ogg/VideoStop_48k.ogg b/data/sounds/effects/material/ogg/VideoStop_48k.ogg
new file mode 100644
index 0000000..b1eb780
--- /dev/null
+++ b/data/sounds/effects/material/ogg/VideoStop_48k.ogg
Binary files differ
diff --git a/packages/ExternalStorageProvider/res/values-uz-rUZ/strings.xml b/packages/ExternalStorageProvider/res/values-uz-rUZ/strings.xml
index d1a956bf..069e137 100644
--- a/packages/ExternalStorageProvider/res/values-uz-rUZ/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-uz-rUZ/strings.xml
@@ -18,5 +18,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"Tashqi xotira"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Ichki xotira"</string>
-    <string name="root_home" msgid="7931555396767513359">"Shaxsiy"</string>
+    <string name="root_home" msgid="7931555396767513359">"Mening fayllarim"</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java
deleted file mode 100644
index 844b216..0000000
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java
+++ /dev/null
@@ -1,91 +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.mtp;
-
-import android.content.res.Resources;
-import android.database.MatrixCursor;
-import android.media.MediaFile;
-import android.mtp.MtpConstants;
-import android.mtp.MtpObjectInfo;
-import android.provider.DocumentsContract;
-import android.provider.DocumentsContract.Document;
-
-/**
- * TODO Remove this class after we switch to use MtpDatabase.
- */
-final class CursorHelper {
-    static final int DUMMY_HANDLE_FOR_ROOT = 0;
-
-    private CursorHelper() {
-    }
-
-    static void addToCursor(Resources resources, MtpRoot root, MatrixCursor.RowBuilder builder) {
-        final Identifier identifier = new Identifier(
-                root.mDeviceId, root.mStorageId, DUMMY_HANDLE_FOR_ROOT);
-        builder.add(Document.COLUMN_DOCUMENT_ID, identifier.toDocumentId());
-        builder.add(Document.COLUMN_DISPLAY_NAME, root.getRootName(resources));
-        builder.add(Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR);
-        builder.add(Document.COLUMN_LAST_MODIFIED, null);
-        builder.add(Document.COLUMN_FLAGS, 0);
-        builder.add(Document.COLUMN_SIZE,
-                (int) Math.min(root.mMaxCapacity - root.mFreeSpace, Integer.MAX_VALUE));
-    }
-
-    static void addToCursor(MtpObjectInfo objectInfo, Identifier rootIdentifier,
-            MatrixCursor.RowBuilder builder) {
-        final Identifier identifier = new Identifier(
-                rootIdentifier.mDeviceId, rootIdentifier.mStorageId, objectInfo.getObjectHandle());
-        final String mimeType = formatTypeToMimeType(objectInfo.getFormat());
-
-        int flag = 0;
-        if (objectInfo.getProtectionStatus() == 0) {
-            flag |= DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
-                    DocumentsContract.Document.FLAG_SUPPORTS_WRITE;
-            if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
-                flag |= DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE;
-            }
-        }
-        if (objectInfo.getThumbCompressedSize() > 0) {
-            flag |= DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL;
-        }
-
-        builder.add(Document.COLUMN_DOCUMENT_ID, identifier.toDocumentId());
-        builder.add(Document.COLUMN_DISPLAY_NAME, objectInfo.getName());
-        builder.add(Document.COLUMN_MIME_TYPE, mimeType);
-        builder.add(
-                Document.COLUMN_LAST_MODIFIED,
-                objectInfo.getDateModified() != 0 ? objectInfo.getDateModified() : null);
-        builder.add(Document.COLUMN_FLAGS, flag);
-        builder.add(Document.COLUMN_SIZE, objectInfo.getCompressedSize());
-    }
-
-    static String formatTypeToMimeType(int format) {
-        if (format == MtpConstants.FORMAT_ASSOCIATION) {
-            return DocumentsContract.Document.MIME_TYPE_DIR;
-        } else {
-            return MediaFile.getMimeTypeForFormatCode(format);
-        }
-    }
-
-    static int mimeTypeToFormatType(String fileName, String mimeType) {
-        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-            return MtpConstants.FORMAT_ASSOCIATION;
-        } else {
-            return MediaFile.getFormatCode(fileName, mimeType);
-        }
-    }
-}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 1c96906..6fa0df2 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -24,7 +24,6 @@
 import android.os.Bundle;
 import android.os.Process;
 import android.provider.DocumentsContract;
-import android.util.Log;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -75,9 +74,15 @@
             int parentHandle = parent.mObjectHandle;
             // Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to
             // getObjectHandles if we would like to obtain children under the root.
-            if (parentHandle == CursorHelper.DUMMY_HANDLE_FOR_ROOT) {
+            if (parentHandle == Identifier.DUMMY_HANDLE_FOR_ROOT) {
                 parentHandle = MtpManager.OBJECT_HANDLE_ROOT_CHILDREN;
             }
+            // TODO: Handle nit race around here.
+            // 1. getObjectHandles.
+            // 2. putNewDocument.
+            // 3. startAddingChildDocuemnts.
+            // 4. stopAddingChildDocuments - It removes the new document added at the step 2,
+            //     because it is not updated between start/stopAddingChildDocuments.
             task = new LoaderTask(mDatabase, parent, mMtpManager.getObjectHandles(
                     parent.mDeviceId, parent.mStorageId, parentHandle));
             task.fillDocuments(loadDocuments(
@@ -215,8 +220,8 @@
                     throw new IOException(mError);
             }
 
-            final Cursor cursor = mDatabase.queryChildDocuments(
-                    columnNames, mIdentifier.mDocumentId, /* use old ID format */ true);
+            final Cursor cursor =
+                    mDatabase.queryChildDocuments(columnNames, mIdentifier.mDocumentId);
             cursor.setNotificationUri(resolver, createUri());
             cursor.respond(extras);
 
@@ -250,10 +255,10 @@
                 return;
             }
             if (mNumLoaded == 0) {
-                mDatabase.startAddingChildDocuments(mIdentifier.mDocumentId);
+                mDatabase.getMapper().startAddingChildDocuments(mIdentifier.mDocumentId);
             }
             try {
-                mDatabase.putChildDocuments(
+                mDatabase.getMapper().putChildDocuments(
                         mIdentifier.mDeviceId, mIdentifier.mDocumentId, objectInfoList);
                 mNumLoaded += objectInfoList.length;
             } catch (SQLiteException exp) {
@@ -261,7 +266,7 @@
                 mNumLoaded = 0;
             }
             if (getState() != STATE_LOADING) {
-                mDatabase.stopAddingChildDocuments(mIdentifier.mDocumentId);
+                mDatabase.getMapper().stopAddingChildDocuments(mIdentifier.mDocumentId);
             }
         }
 
@@ -270,13 +275,13 @@
             mError = message;
             mNumLoaded = 0;
             if (lastState == STATE_LOADING) {
-                mDatabase.stopAddingChildDocuments(mIdentifier.mDocumentId);
+                mDatabase.getMapper().stopAddingChildDocuments(mIdentifier.mDocumentId);
             }
         }
 
         private Uri createUri() {
             return DocumentsContract.buildChildDocumentsUri(
-                    MtpDocumentsProvider.AUTHORITY, mIdentifier.toDocumentId());
+                    MtpDocumentsProvider.AUTHORITY, mIdentifier.mDocumentId);
         }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
index 4238721e..20b3bf5 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
@@ -16,39 +16,19 @@
 
 package com.android.mtp;
 
+import java.util.Objects;
+
 /**
  * Static utilities for ID.
  */
 class Identifier {
+    final static int DUMMY_HANDLE_FOR_ROOT = 0;
+
     final int mDeviceId;
     final int mStorageId;
     final int mObjectHandle;
     final String mDocumentId;
 
-    static Identifier createFromRootId(String rootId) {
-        final String[] components = rootId.split("_");
-        return new Identifier(
-                Integer.parseInt(components[0]),
-                Integer.parseInt(components[1]));
-    }
-
-    static Identifier createFromDocumentId(String documentId) {
-        final String[] components = documentId.split("_");
-        return new Identifier(
-                Integer.parseInt(components[0]),
-                Integer.parseInt(components[1]),
-                Integer.parseInt(components[2]));
-    }
-
-
-    Identifier(int deviceId, int storageId) {
-        this(deviceId, storageId, CursorHelper.DUMMY_HANDLE_FOR_ROOT);
-    }
-
-    Identifier(int deviceId, int storageId, int objectHandle) {
-        this(deviceId, storageId, objectHandle, null);
-    }
-
     Identifier(int deviceId, int storageId, int objectHandle, String documentId) {
         mDeviceId = deviceId;
         mStorageId = storageId;
@@ -56,16 +36,6 @@
         mDocumentId = documentId;
     }
 
-    // TODO: Make the ID persistent.
-    String toRootId() {
-        return String.format("%d_%d", mDeviceId, mStorageId);
-    }
-
-    // TODO: Make the ID persistent.
-    String toDocumentId() {
-        return String.format("%d_%d_%d", mDeviceId, mStorageId, mObjectHandle);
-    }
-
     @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof Identifier))
@@ -77,6 +47,6 @@
 
     @Override
     public int hashCode() {
-        return (mDeviceId << 16) ^ (mStorageId << 8) ^ mObjectHandle;
+        return Objects.hash(mDeviceId, mStorageId, mObjectHandle, mDocumentId);
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
new file mode 100644
index 0000000..0d9d60c
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
@@ -0,0 +1,513 @@
+/*
+ * 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.mtp;
+
+import static com.android.mtp.MtpDatabaseConstants.*;
+
+import android.content.ContentValues;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.mtp.MtpObjectInfo;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.android.mtp.MtpDatabase.strings;
+
+
+/**
+ * Mapping operations for MtpDatabase.
+ * Also see the comments of {@link MtpDatabase}.
+ */
+class Mapper {
+    private final MtpDatabase mDatabase;
+
+    /**
+     * Mapping mode for roots/documents where we start adding child documents.
+     * Methods operate the state needs to be synchronized.
+     */
+    private final Map<String, Integer> mMappingMode = new HashMap<>();
+
+    Mapper(MtpDatabase database) {
+        mDatabase = database;
+    }
+
+    /**
+     * Invokes {@link #startAddingDocuments} for root documents.
+     * @param deviceId Device ID.
+     */
+    synchronized void startAddingRootDocuments(int deviceId) {
+        final String mappingStateKey = getRootDocumentsMappingStateKey(deviceId);
+        Preconditions.checkState(!mMappingMode.containsKey(mappingStateKey));
+        mMappingMode.put(
+                mappingStateKey,
+                startAddingDocuments(
+                        SELECTION_ROOT_DOCUMENTS, Integer.toString(deviceId)));
+    }
+
+    /**
+     * Invokes {@link #startAddingDocuments} for child of specific documents.
+     * @param parentDocumentId Document ID for parent document.
+     */
+    @VisibleForTesting
+    synchronized void startAddingChildDocuments(String parentDocumentId) {
+        final String mappingStateKey = getChildDocumentsMappingStateKey(parentDocumentId);
+        Preconditions.checkState(!mMappingMode.containsKey(mappingStateKey));
+        mMappingMode.put(
+                mappingStateKey,
+                startAddingDocuments(SELECTION_CHILD_DOCUMENTS, parentDocumentId));
+    }
+
+    /**
+     * Puts root information to database.
+     * @param deviceId Device ID
+     * @param resources Resources required to localize root name.
+     * @param roots List of root information.
+     * @return If roots are added or removed from the database.
+     */
+    synchronized boolean putRootDocuments(int deviceId, Resources resources, MtpRoot[] roots) {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        database.beginTransaction();
+        try {
+            final boolean heuristic;
+            final String mapColumn;
+            final String key = getRootDocumentsMappingStateKey(deviceId);
+            Preconditions.checkState(mMappingMode.containsKey(key));
+            switch (mMappingMode.get(key)) {
+                case MAP_BY_MTP_IDENTIFIER:
+                    heuristic = false;
+                    mapColumn = COLUMN_STORAGE_ID;
+                    break;
+                case MAP_BY_NAME:
+                    heuristic = true;
+                    mapColumn = Document.COLUMN_DISPLAY_NAME;
+                    break;
+                default:
+                    throw new Error("Unexpected map mode.");
+            }
+            final ContentValues[] valuesList = new ContentValues[roots.length];
+            for (int i = 0; i < roots.length; i++) {
+                if (roots[i].mDeviceId != deviceId) {
+                    throw new IllegalArgumentException();
+                }
+                valuesList[i] = new ContentValues();
+                MtpDatabase.getRootDocumentValues(valuesList[i], resources, roots[i]);
+            }
+            final boolean changed = putDocuments(
+                    valuesList,
+                    SELECTION_ROOT_DOCUMENTS,
+                    Integer.toString(deviceId),
+                    heuristic,
+                    mapColumn);
+            final ContentValues values = new ContentValues();
+            int i = 0;
+            for (final MtpRoot root : roots) {
+                // Use the same value for the root ID and the corresponding document ID.
+                final String documentId = valuesList[i++].getAsString(Document.COLUMN_DOCUMENT_ID);
+                // If it fails to insert/update documents, the document ID will be set with -1.
+                // In this case we don't insert/update root extra information neither.
+                if (documentId == null) {
+                    continue;
+                }
+                values.put(Root.COLUMN_ROOT_ID, documentId);
+                values.put(
+                        Root.COLUMN_FLAGS,
+                        Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE);
+                values.put(Root.COLUMN_AVAILABLE_BYTES, root.mFreeSpace);
+                values.put(Root.COLUMN_CAPACITY_BYTES, root.mMaxCapacity);
+                values.put(Root.COLUMN_MIME_TYPES, "");
+                database.replace(TABLE_ROOT_EXTRA, null, values);
+            }
+            database.setTransactionSuccessful();
+            return changed;
+        } finally {
+            database.endTransaction();
+        }
+    }
+
+    /**
+     * Puts document information to database.
+     * @param deviceId Device ID
+     * @param parentId Parent document ID.
+     * @param documents List of document information.
+     */
+    synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) {
+        final boolean heuristic;
+        final String mapColumn;
+        final String key = getChildDocumentsMappingStateKey(parentId);
+        Preconditions.checkState(mMappingMode.containsKey(key));
+        switch (mMappingMode.get(key)) {
+            case MAP_BY_MTP_IDENTIFIER:
+                heuristic = false;
+                mapColumn = COLUMN_OBJECT_HANDLE;
+                break;
+            case MAP_BY_NAME:
+                heuristic = true;
+                mapColumn = Document.COLUMN_DISPLAY_NAME;
+                break;
+            default:
+                throw new Error("Unexpected map mode.");
+        }
+        final ContentValues[] valuesList = new ContentValues[documents.length];
+        for (int i = 0; i < documents.length; i++) {
+            valuesList[i] = new ContentValues();
+            MtpDatabase.getChildDocumentValues(
+                    valuesList[i], deviceId, parentId, documents[i]);
+        }
+        putDocuments(
+                valuesList, SELECTION_CHILD_DOCUMENTS, parentId, heuristic, mapColumn);
+    }
+
+    /**
+     * Stops adding root documents.
+     * @param deviceId Device ID.
+     * @return True if new rows are added/removed.
+     */
+    synchronized boolean stopAddingRootDocuments(int deviceId) {
+        final String key = getRootDocumentsMappingStateKey(deviceId);
+        Preconditions.checkState(mMappingMode.containsKey(key));
+        switch (mMappingMode.get(key)) {
+            case MAP_BY_MTP_IDENTIFIER:
+                mMappingMode.remove(key);
+                return stopAddingDocuments(
+                        SELECTION_ROOT_DOCUMENTS,
+                        Integer.toString(deviceId),
+                        COLUMN_STORAGE_ID);
+            case MAP_BY_NAME:
+                mMappingMode.remove(key);
+                return stopAddingDocuments(
+                        SELECTION_ROOT_DOCUMENTS,
+                        Integer.toString(deviceId),
+                        Document.COLUMN_DISPLAY_NAME);
+            default:
+                throw new Error("Unexpected mapping state.");
+        }
+    }
+
+    /**
+     * Stops adding documents under the parent.
+     * @param parentId Document ID of the parent.
+     */
+    synchronized void stopAddingChildDocuments(String parentId) {
+        final String key = getChildDocumentsMappingStateKey(parentId);
+        Preconditions.checkState(mMappingMode.containsKey(key));
+        switch (mMappingMode.get(key)) {
+            case MAP_BY_MTP_IDENTIFIER:
+                stopAddingDocuments(
+                        SELECTION_CHILD_DOCUMENTS,
+                        parentId,
+                        COLUMN_OBJECT_HANDLE);
+                break;
+            case MAP_BY_NAME:
+                stopAddingDocuments(
+                        SELECTION_CHILD_DOCUMENTS,
+                        parentId,
+                        Document.COLUMN_DISPLAY_NAME);
+                break;
+            default:
+                throw new Error("Unexpected mapping state.");
+        }
+        mMappingMode.remove(key);
+    }
+
+    @VisibleForTesting
+    void clearMapping() {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        database.beginTransaction();
+        try {
+            mDatabase.deleteDocumentsAndRootsRecursively(
+                    COLUMN_ROW_STATE + " = ?", strings(ROW_STATE_PENDING));
+            final ContentValues values = new ContentValues();
+            values.putNull(COLUMN_OBJECT_HANDLE);
+            values.putNull(COLUMN_STORAGE_ID);
+            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
+            database.update(TABLE_DOCUMENTS, values, null, null);
+            database.setTransactionSuccessful();
+            mMappingMode.clear();
+        } finally {
+            database.endTransaction();
+        }
+    }
+
+    /**
+     * Starts adding new documents.
+     * The methods decides mapping mode depends on if all documents under the given parent have MTP
+     * identifier or not. If all the documents have MTP identifier, it uses the identifier to find
+     * a corresponding existing row. Otherwise it does heuristic.
+     *
+     * @param selection Query matches valid documents.
+     * @param arg Argument for selection.
+     * @return Mapping mode.
+     */
+    private int startAddingDocuments(String selection, String arg) {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        database.beginTransaction();
+        try {
+            // Delete all pending rows.
+            mDatabase.deleteDocumentsAndRootsRecursively(
+                    selection + " AND " + COLUMN_ROW_STATE + "=?", strings(arg, ROW_STATE_PENDING));
+
+            // Set all documents as invalidated.
+            final ContentValues values = new ContentValues();
+            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
+            database.update(TABLE_DOCUMENTS, values, selection, new String[] { arg });
+
+            // If we have rows that does not have MTP identifier, do heuristic mapping by name.
+            final boolean useNameForResolving = DatabaseUtils.queryNumEntries(
+                    database,
+                    TABLE_DOCUMENTS,
+                    selection + " AND " + COLUMN_STORAGE_ID + " IS NULL",
+                    new String[] { arg }) > 0;
+            database.setTransactionSuccessful();
+            return useNameForResolving ? MAP_BY_NAME : MAP_BY_MTP_IDENTIFIER;
+        } finally {
+            database.endTransaction();
+        }
+    }
+
+    /**
+     * Puts the documents into the database.
+     * If the mapping mode is not heuristic, it just adds the rows to the database or updates the
+     * existing rows with the new values. If the mapping mode is heuristic, it adds some new rows as
+     * 'pending' state when that rows may be corresponding to existing 'invalidated' rows. Then
+     * {@link #stopAddingDocuments(String, String, String)} turns the pending rows into 'valid'
+     * rows. If the methods adds rows to database, it updates valueList with correct document ID.
+     *
+     * @param valuesList Values for documents to be stored in the database.
+     * @param selection SQL where closure to select rows that shares the same parent.
+     * @param arg Argument for selection SQL.
+     * @param heuristic Whether the mapping mode is heuristic.
+     * @return Whether the method adds new rows.
+     */
+    private boolean putDocuments(
+            ContentValues[] valuesList,
+            String selection,
+            String arg,
+            boolean heuristic,
+            String mappingKey) {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        boolean added = false;
+        database.beginTransaction();
+        try {
+            for (final ContentValues values : valuesList) {
+                final Cursor candidateCursor = database.query(
+                        TABLE_DOCUMENTS,
+                        strings(Document.COLUMN_DOCUMENT_ID),
+                        selection + " AND " +
+                        COLUMN_ROW_STATE + "=? AND " +
+                        mappingKey + "=?",
+                        strings(arg, ROW_STATE_INVALIDATED, values.getAsString(mappingKey)),
+                        null,
+                        null,
+                        null,
+                        "1");
+                try {
+                    final long rowId;
+                    if (candidateCursor.getCount() == 0) {
+                        rowId = database.insert(TABLE_DOCUMENTS, null, values);
+                        if (rowId == -1) {
+                            throw new SQLiteException("Failed to put a document into database.");
+                        }
+                        added = true;
+                    } else if (!heuristic) {
+                        candidateCursor.moveToNext();
+                        final String documentId = candidateCursor.getString(0);
+                        rowId = database.update(
+                                TABLE_DOCUMENTS,
+                                values,
+                                SELECTION_DOCUMENT_ID,
+                                strings(documentId));
+                    } else {
+                        values.put(COLUMN_ROW_STATE, ROW_STATE_PENDING);
+                        rowId = database.insert(TABLE_DOCUMENTS, null, values);
+                    }
+                    // Document ID is a primary integer key of the table. So the returned row
+                    // IDs should be same with the document ID.
+                    values.put(Document.COLUMN_DOCUMENT_ID, rowId);
+                } finally {
+                    candidateCursor.close();
+                }
+            }
+
+            database.setTransactionSuccessful();
+            return added;
+        } finally {
+            database.endTransaction();
+        }
+    }
+
+    /**
+     * Maps 'pending' document and 'invalidated' document that shares the same column of groupKey.
+     * If the database does not find corresponding 'invalidated' document, it just removes
+     * 'invalidated' document from the database.
+     * @param selection Query to select rows for resolving.
+     * @param arg Argument for selection SQL.
+     * @param groupKey Column name used to find corresponding rows.
+     * @return Whether the methods adds or removed visible rows.
+     */
+    private boolean stopAddingDocuments(String selection, String arg, String groupKey) {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        database.beginTransaction();
+        try {
+            // Get 1-to-1 mapping of invalidated document and pending document.
+            final String invalidatedIdQuery = createStateFilter(
+                    ROW_STATE_INVALIDATED, Document.COLUMN_DOCUMENT_ID);
+            final String pendingIdQuery = createStateFilter(
+                    ROW_STATE_PENDING, Document.COLUMN_DOCUMENT_ID);
+            // SQL should be like:
+            // SELECT group_concat(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END),
+            //        group_concat(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END)
+            // WHERE device_id = ? AND parent_document_id IS NULL
+            // GROUP BY display_name
+            // HAVING count(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END) = 1 AND
+            //        count(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END) = 1
+            final Cursor mergingCursor = database.query(
+                    TABLE_DOCUMENTS,
+                    new String[] {
+                            "group_concat(" + invalidatedIdQuery + ")",
+                            "group_concat(" + pendingIdQuery + ")"
+                    },
+                    selection,
+                    strings(arg),
+                    groupKey,
+                    "count(" + invalidatedIdQuery + ") = 1 AND count(" + pendingIdQuery + ") = 1",
+                    null);
+
+            final ContentValues values = new ContentValues();
+            while (mergingCursor.moveToNext()) {
+                final String invalidatedId = mergingCursor.getString(0);
+                final String pendingId = mergingCursor.getString(1);
+
+                // Obtain the new values including the latest object handle from mapping row.
+                getFirstRow(
+                        TABLE_DOCUMENTS,
+                        SELECTION_DOCUMENT_ID,
+                        new String[] { pendingId },
+                        values);
+                values.remove(Document.COLUMN_DOCUMENT_ID);
+                values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
+                database.update(
+                        TABLE_DOCUMENTS,
+                        values,
+                        SELECTION_DOCUMENT_ID,
+                        new String[] { invalidatedId });
+
+                getFirstRow(
+                        TABLE_ROOT_EXTRA,
+                        SELECTION_ROOT_ID,
+                        new String[] { pendingId },
+                        values);
+                if (values.size() > 0) {
+                    values.remove(Root.COLUMN_ROOT_ID);
+                    database.update(
+                            TABLE_ROOT_EXTRA,
+                            values,
+                            SELECTION_ROOT_ID,
+                            new String[] { invalidatedId });
+                }
+
+                // Delete 'pending' row.
+                mDatabase.deleteDocumentsAndRootsRecursively(
+                        SELECTION_DOCUMENT_ID, new String[] { pendingId });
+            }
+            mergingCursor.close();
+
+            boolean changed = false;
+
+            // Delete all invalidated rows that cannot be mapped.
+            if (mDatabase.deleteDocumentsAndRootsRecursively(
+                    COLUMN_ROW_STATE + " = ? AND " + selection,
+                    strings(ROW_STATE_INVALIDATED, arg))) {
+                changed = true;
+            }
+
+            // The database cannot find old document ID for the pending rows.
+            // Turn the all pending rows into valid state, which means the rows become to be
+            // valid with new document ID.
+            values.clear();
+            values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
+            if (database.update(
+                    TABLE_DOCUMENTS,
+                    values,
+                    COLUMN_ROW_STATE + " = ? AND " + selection,
+                    strings(ROW_STATE_PENDING, arg)) != 0) {
+                changed = true;
+            }
+            database.setTransactionSuccessful();
+            return changed;
+        } finally {
+            database.endTransaction();
+        }
+    }
+
+    /**
+     * Obtains values of the first row for the query.
+     * @param values ContentValues that the values are stored to.
+     * @param table Target table.
+     * @param selection Query to select rows.
+     * @param args Argument for query.
+     */
+    private void getFirstRow(String table, String selection, String[] args, ContentValues values) {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        values.clear();
+        final Cursor cursor = database.query(table, null, selection, args, null, null, null, "1");
+        if (cursor.getCount() == 0) {
+            return;
+        }
+        cursor.moveToNext();
+        DatabaseUtils.cursorRowToContentValues(cursor, values);
+        cursor.close();
+    }
+
+    /**
+     * Gets SQL expression that represents the given value or NULL depends on the row state.
+     * You must pass static constants to this methods otherwise you may be suffered from SQL
+     * injections.
+     * @param state Expected row state.
+     * @param a SQL value.
+     * @return Expression that represents a if the row state is expected one, and represents NULL
+     *     otherwise.
+     */
+    private static String createStateFilter(int state, String a) {
+        return "CASE WHEN " + COLUMN_ROW_STATE + " = " + Integer.toString(state) +
+                " THEN " + a + " ELSE NULL END";
+    }
+
+    /**
+     * @param deviceId Device ID.
+     * @return Key for {@link #mMappingMode}.
+     */
+    private static String getRootDocumentsMappingStateKey(int deviceId) {
+        return "RootDocuments/" + deviceId;
+    }
+
+    /**
+     * @param parentDocumentId Document ID for the parent document.
+     * @return Key for {@link #mMappingMode}.
+     */
+    private static String getChildDocumentsMappingStateKey(String parentDocumentId) {
+        return "ChildDocuments/" + parentDocumentId;
+    }
+}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 3dc69cc..00fe7a7 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -22,6 +22,12 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.media.MediaFile;
+import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
@@ -29,8 +35,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Objects;
 
 /**
  * Database for MTP objects.
@@ -46,13 +53,13 @@
  * by comparing the directory structure and object name.
  *
  * To start putting documents into the database, the client needs to call
- * {@link #startAddingChildDocuments(String)} with the parent document ID. Also it needs to call
- * {@link #stopAddingChildDocuments(String)} after putting all child documents to the database.
- * (All explanations are same for root documents)
+ * {@link Mapper#startAddingChildDocuments(String)} with the parent document ID. Also it
+ * needs to call {@link Mapper#stopAddingChildDocuments(String)} after putting all child
+ * documents to the database. (All explanations are same for root documents)
  *
- * database.startAddingChildDocuments();
- * database.putChildDocuments();
- * database.stopAddingChildDocuments();
+ * database.getMapper().startAddingChildDocuments();
+ * database.getMapper().putChildDocuments();
+ * database.getMapper().stopAddingChildDocuments();
  *
  * To update the existing documents, the client code can repeat to call the three methods again.
  * The newly added rows update corresponding existing rows that have same MTP identifier like
@@ -66,170 +73,232 @@
  * the database tries to find corresponding rows by using document's name instead of MTP identifier
  * at the next update cycle.
  *
- * TODO: Remove @VisibleForTesting annotation when we start to use this class.
  * TODO: Improve performance by SQL optimization.
  */
-@VisibleForTesting
 class MtpDatabase {
-    private final MtpDatabaseInternal mDatabase;
+    private final SQLiteDatabase mDatabase;
+    private final Mapper mMapper;
 
-    /**
-     * Mapping mode for roots/documents where we start adding child documents.
-     * Methods operate the state needs to be synchronized.
-     */
-    private final Map<String, Integer> mMappingMode = new HashMap<>();
-
-    @VisibleForTesting
-    MtpDatabase(Context context, int flags) {
-        mDatabase = new MtpDatabaseInternal(context, flags);
+    SQLiteDatabase getSQLiteDatabase() {
+        return mDatabase;
     }
 
-    /**
-     * Closes the database.
-     */
-    @VisibleForTesting
+    MtpDatabase(Context context, int flags) {
+        final OpenHelper helper = new OpenHelper(context, flags);
+        mDatabase = helper.getWritableDatabase();
+        mMapper = new Mapper(this);
+    }
+
     void close() {
         mDatabase.close();
     }
 
     /**
-     * {@link MtpDatabaseInternal#queryRoots}
+     * Returns operations for mapping.
+     * @return Mapping operations.
      */
-    Cursor queryRoots(String[] columnNames) {
-        return mDatabase.queryRoots(columnNames);
+    Mapper getMapper() {
+        return mMapper;
     }
 
     /**
-     * {@link MtpDatabaseInternal#queryRootDocuments}
+     * Queries roots information.
+     * @param columnNames Column names defined in {@link android.provider.DocumentsContract.Root}.
+     * @return Database cursor.
+     */
+    Cursor queryRoots(String[] columnNames) {
+        return mDatabase.query(
+                VIEW_ROOTS,
+                columnNames,
+                COLUMN_ROW_STATE + " IN (?, ?)",
+                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED),
+                null,
+                null,
+                null);
+    }
+
+    /**
+     * Queries root documents information.
+     * @param columnNames Column names defined in
+     *     {@link android.provider.DocumentsContract.Document}.
+     * @return Database cursor.
      */
     @VisibleForTesting
     Cursor queryRootDocuments(String[] columnNames) {
-        return mDatabase.queryRootDocuments(columnNames);
+        return mDatabase.query(
+                TABLE_DOCUMENTS,
+                columnNames,
+                COLUMN_ROW_STATE + " IN (?, ?)",
+                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED),
+                null,
+                null,
+                null);
     }
 
     /**
-     * {@link MtpDatabaseInternal#queryChildDocuments}
+     * Queries documents information.
+     * @param columnNames Column names defined in
+     *     {@link android.provider.DocumentsContract.Document}.
+     * @return Database cursor.
      */
-    @VisibleForTesting
     Cursor queryChildDocuments(String[] columnNames, String parentDocumentId) {
-        return queryChildDocuments(columnNames, parentDocumentId, false);
-    }
-
-    @VisibleForTesting
-    Cursor queryChildDocuments(String[] columnNames, String parentDocumentId, boolean useOldId) {
-        final String[] newColumnNames = new String[columnNames.length];
-
-        // TODO: Temporary replace document ID with old format.
-        for (int i = 0; i < columnNames.length; i++) {
-            if (useOldId && DocumentsContract.Document.COLUMN_DOCUMENT_ID.equals(columnNames[i])) {
-                newColumnNames[i] = COLUMN_DEVICE_ID + " || '_' || " + COLUMN_STORAGE_ID +
-                        " || '_' || IFNULL(" + COLUMN_OBJECT_HANDLE + ",0) AS " +
-                        DocumentsContract.Document.COLUMN_DOCUMENT_ID;
-            } else {
-                newColumnNames[i] = columnNames[i];
-            }
-        }
-
-        return mDatabase.queryChildDocuments(newColumnNames, parentDocumentId);
-    }
-
-    Identifier createIdentifier(String parentDocumentId) {
-        return mDatabase.createIdentifier(parentDocumentId);
+        return mDatabase.query(
+                TABLE_DOCUMENTS,
+                columnNames,
+                COLUMN_ROW_STATE + " IN (?, ?) AND " + COLUMN_PARENT_DOCUMENT_ID + " = ?",
+                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED, parentDocumentId),
+                null,
+                null,
+                null);
     }
 
     /**
-     * {@link MtpDatabaseInternal#removeDeviceRows}
+     * Queries a single document.
+     * @param documentId
+     * @param projection
+     * @return Database cursor.
      */
-    void removeDeviceRows(int deviceId) {
-        mDatabase.removeDeviceRows(deviceId);
+    public Cursor queryDocument(String documentId, String[] projection) {
+        return mDatabase.query(
+                TABLE_DOCUMENTS,
+                projection,
+                SELECTION_DOCUMENT_ID,
+                strings(documentId),
+                null,
+                null,
+                null,
+                "1");
     }
 
     /**
-     * Invokes {@link MtpDatabaseInternal#startAddingDocuments} for root documents.
+     * Remove all rows belong to a device.
      * @param deviceId Device ID.
      */
-    synchronized void startAddingRootDocuments(int deviceId) {
-        final String mappingStateKey = getRootDocumentsMappingStateKey(deviceId);
-        if (mMappingMode.containsKey(mappingStateKey)) {
-            throw new Error("Mapping for the root has already started.");
-        }
-        mMappingMode.put(
-                mappingStateKey,
-                mDatabase.startAddingDocuments(
-                        SELECTION_ROOT_DOCUMENTS, Integer.toString(deviceId)));
+    void removeDeviceRows(int deviceId) {
+        // Call non-recursive version because it anyway deletes all rows in the devices.
+        deleteDocumentsAndRoots(COLUMN_DEVICE_ID + "=?", strings(deviceId));
     }
 
     /**
-     * Invokes {@link MtpDatabaseInternal#startAddingDocuments} for child of specific documents.
-     * @param parentDocumentId Document ID for parent document.
+     * Obtains parent document ID.
+     * @param documentId
+     * @return parent document ID.
+     * @throws FileNotFoundException
      */
-    @VisibleForTesting
-    synchronized void startAddingChildDocuments(String parentDocumentId) {
-        final String mappingStateKey = getChildDocumentsMappingStateKey(parentDocumentId);
-        if (mMappingMode.containsKey(mappingStateKey)) {
-            throw new Error("Mapping for the root has already started.");
+    String getParentId(String documentId) throws FileNotFoundException {
+        final Cursor cursor = mDatabase.query(
+                TABLE_DOCUMENTS,
+                strings(COLUMN_PARENT_DOCUMENT_ID),
+                SELECTION_DOCUMENT_ID,
+                strings(documentId),
+                null,
+                null,
+                null,
+                "1");
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
+            } else {
+                throw new FileNotFoundException("Cannot find a row having ID=" + documentId);
+            }
+        } finally {
+            cursor.close();
         }
-        mMappingMode.put(
-                mappingStateKey,
-                mDatabase.startAddingDocuments(SELECTION_CHILD_DOCUMENTS, parentDocumentId));
     }
 
     /**
-     * Puts root information to database.
-     * @param deviceId Device ID
-     * @param resources Resources required to localize root name.
-     * @param roots List of root information.
-     * @return If roots are added or removed from the database.
+     * Adds new document under the parent.
+     * The method does not affect invalidated and pending documents because we know the document is
+     * newly added and never mapped with existing ones.
+     * @param parentDocumentId
+     * @param info
+     * @return Document ID of added document.
      */
-    synchronized boolean putRootDocuments(int deviceId, Resources resources, MtpRoot[] roots) {
+    String putNewDocument(int deviceId, String parentDocumentId, MtpObjectInfo info) {
+        final ContentValues values = new ContentValues();
+        getChildDocumentValues(values, deviceId, parentDocumentId, info);
         mDatabase.beginTransaction();
         try {
-            final boolean heuristic;
-            final String mapColumn;
-            switch (mMappingMode.get(getRootDocumentsMappingStateKey(deviceId))) {
-                case MAP_BY_MTP_IDENTIFIER:
-                    heuristic = false;
-                    mapColumn = COLUMN_STORAGE_ID;
-                    break;
-                case MAP_BY_NAME:
-                    heuristic = true;
-                    mapColumn = Document.COLUMN_DISPLAY_NAME;
-                    break;
-                default:
-                    throw new Error("Unexpected map mode.");
+            final long id = mDatabase.insert(TABLE_DOCUMENTS, null, values);
+            mDatabase.setTransactionSuccessful();
+            return Long.toString(id);
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * Deletes document and its children.
+     * @param documentId
+     */
+    void deleteDocument(String documentId) {
+        deleteDocumentsAndRootsRecursively(SELECTION_DOCUMENT_ID, strings(documentId));
+    }
+
+    /**
+     * Gets identifier from document ID.
+     * @param documentId Document ID.
+     * @return Identifier.
+     * @throws FileNotFoundException
+     */
+    Identifier createIdentifier(String documentId) throws FileNotFoundException {
+        // Currently documentId is old format.
+        final Cursor cursor = mDatabase.query(
+                TABLE_DOCUMENTS,
+                strings(COLUMN_DEVICE_ID, COLUMN_STORAGE_ID, COLUMN_OBJECT_HANDLE),
+                SELECTION_DOCUMENT_ID,
+                strings(documentId),
+                null,
+                null,
+                null,
+                "1");
+        try {
+            if (cursor.getCount() == 0) {
+                throw new FileNotFoundException("ID is not found.");
+            } else {
+                cursor.moveToNext();
+                return new Identifier(
+                        cursor.getInt(0),
+                        cursor.getInt(1),
+                        cursor.isNull(2) ? Identifier.DUMMY_HANDLE_FOR_ROOT : cursor.getInt(2),
+                        documentId);
             }
-            final ContentValues[] valuesList = new ContentValues[roots.length];
-            for (int i = 0; i < roots.length; i++) {
-                if (roots[i].mDeviceId != deviceId) {
-                    throw new IllegalArgumentException();
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Deletes a document, and its root information if the document is a root document.
+     * @param selection Query to select documents.
+     * @param args Arguments for selection.
+     * @return Whether the method deletes rows.
+     */
+    boolean deleteDocumentsAndRootsRecursively(String selection, String[] args) {
+        mDatabase.beginTransaction();
+        try {
+            boolean changed = false;
+            final Cursor cursor = mDatabase.query(
+                    TABLE_DOCUMENTS,
+                    strings(Document.COLUMN_DOCUMENT_ID),
+                    selection,
+                    args,
+                    null,
+                    null,
+                    null);
+            try {
+                while (cursor.moveToNext()) {
+                    if (deleteDocumentsAndRootsRecursively(
+                            COLUMN_PARENT_DOCUMENT_ID + "=?",
+                            strings(cursor.getString(0)))) {
+                        changed = true;
+                    }
                 }
-                valuesList[i] = new ContentValues();
-                getRootDocumentValues(valuesList[i], resources, roots[i]);
+            } finally {
+                cursor.close();
             }
-            final boolean changed = mDatabase.putDocuments(
-                    valuesList,
-                    SELECTION_ROOT_DOCUMENTS,
-                    Integer.toString(deviceId),
-                    heuristic,
-                    mapColumn);
-            final ContentValues values = new ContentValues();
-            int i = 0;
-            for (final MtpRoot root : roots) {
-                // Use the same value for the root ID and the corresponding document ID.
-                final String documentId = valuesList[i++].getAsString(Document.COLUMN_DOCUMENT_ID);
-                // If it fails to insert/update documents, the document ID will be set with -1.
-                // In this case we don't insert/update root extra information neither.
-                if (documentId == null) {
-                    continue;
-                }
-                values.put(Root.COLUMN_ROOT_ID, documentId);
-                values.put(
-                        Root.COLUMN_FLAGS,
-                        Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE);
-                values.put(Root.COLUMN_AVAILABLE_BYTES, root.mFreeSpace);
-                values.put(Root.COLUMN_CAPACITY_BYTES, root.mMaxCapacity);
-                values.put(Root.COLUMN_MIME_TYPES, "");
-                mDatabase.putRootExtra(values);
+            if (deleteDocumentsAndRoots(selection, args)) {
+                changed = true;
             }
             mDatabase.setTransactionSuccessful();
             return changed;
@@ -239,94 +308,80 @@
     }
 
     /**
-     * Puts document information to database.
-     * @param deviceId Device ID
-     * @param parentId Parent document ID.
-     * @param documents List of document information.
+     * Returns the set of device ID stored in the database.
      */
-    @VisibleForTesting
-    synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) {
-        final boolean heuristic;
-        final String mapColumn;
-        switch (mMappingMode.get(getChildDocumentsMappingStateKey(parentId))) {
-            case MAP_BY_MTP_IDENTIFIER:
-                heuristic = false;
-                mapColumn = COLUMN_OBJECT_HANDLE;
-                break;
-            case MAP_BY_NAME:
-                heuristic = true;
-                mapColumn = Document.COLUMN_DISPLAY_NAME;
-                break;
-            default:
-                throw new Error("Unexpected map mode.");
-        }
-        final ContentValues[] valuesList = new ContentValues[documents.length];
-        for (int i = 0; i < documents.length; i++) {
-            valuesList[i] = new ContentValues();
-            getChildDocumentValues(valuesList[i], deviceId, parentId, documents[i]);
-        }
-        mDatabase.putDocuments(
-                valuesList, SELECTION_CHILD_DOCUMENTS, parentId, heuristic, mapColumn);
-    }
-
-    /**
-     * Clears mapping between MTP identifier and document/root ID.
-     */
-    @VisibleForTesting
-    synchronized void clearMapping() {
-        mDatabase.clearMapping();
-        mMappingMode.clear();
-    }
-
-    /**
-     * Stops adding root documents.
-     * @param deviceId Device ID.
-     * @return True if new rows are added/removed.
-     */
-    synchronized boolean stopAddingRootDocuments(int deviceId) {
-        final String mappingModeKey = getRootDocumentsMappingStateKey(deviceId);
-        switch (mMappingMode.get(mappingModeKey)) {
-            case MAP_BY_MTP_IDENTIFIER:
-                mMappingMode.remove(mappingModeKey);
-                return mDatabase.stopAddingDocuments(
-                        SELECTION_ROOT_DOCUMENTS,
-                        Integer.toString(deviceId),
-                        COLUMN_STORAGE_ID);
-            case MAP_BY_NAME:
-                mMappingMode.remove(mappingModeKey);
-                return mDatabase.stopAddingDocuments(
-                        SELECTION_ROOT_DOCUMENTS,
-                        Integer.toString(deviceId),
-                        Document.COLUMN_DISPLAY_NAME);
-            default:
-                throw new Error("Unexpected mapping state.");
+    int[] getDeviceIds() {
+        final Cursor cursor = mDatabase.query(
+                true,
+                TABLE_DOCUMENTS,
+                strings(COLUMN_DEVICE_ID),
+                null,
+                null,
+                null,
+                null,
+                null,
+                null);
+        try {
+            final int[] ids = new int[cursor.getCount()];
+            for (int i = 0; i < ids.length; i++) {
+                cursor.moveToNext();
+                ids[i] = cursor.getInt(0);
+            }
+            return ids;
+        } finally {
+            cursor.close();
         }
     }
 
-    /**
-     * Stops adding documents under the parent.
-     * @param parentId Document ID of the parent.
-     */
-    @VisibleForTesting
-    synchronized void stopAddingChildDocuments(String parentId) {
-        final String mappingModeKey = getChildDocumentsMappingStateKey(parentId);
-        switch (mMappingMode.get(mappingModeKey)) {
-            case MAP_BY_MTP_IDENTIFIER:
-                mDatabase.stopAddingDocuments(
-                        SELECTION_CHILD_DOCUMENTS,
-                        parentId,
-                        COLUMN_OBJECT_HANDLE);
-                break;
-            case MAP_BY_NAME:
-                mDatabase.stopAddingDocuments(
-                        SELECTION_CHILD_DOCUMENTS,
-                        parentId,
-                        Document.COLUMN_DISPLAY_NAME);
-                break;
-            default:
-                throw new Error("Unexpected mapping state.");
+    private boolean deleteDocumentsAndRoots(String selection, String[] args) {
+        mDatabase.beginTransaction();
+        try {
+            int deleted = 0;
+            deleted += mDatabase.delete(
+                    TABLE_ROOT_EXTRA,
+                    Root.COLUMN_ROOT_ID + " IN (" + SQLiteQueryBuilder.buildQueryString(
+                            false,
+                            TABLE_DOCUMENTS,
+                            new String[] { Document.COLUMN_DOCUMENT_ID },
+                            selection,
+                            null,
+                            null,
+                            null,
+                            null) + ")",
+                    args);
+            deleted += mDatabase.delete(TABLE_DOCUMENTS, selection, args);
+            mDatabase.setTransactionSuccessful();
+            // TODO Remove mappingState.
+            return deleted != 0;
+        } finally {
+            mDatabase.endTransaction();
         }
-        mMappingMode.remove(mappingModeKey);
+    }
+
+    private static class OpenHelper extends SQLiteOpenHelper {
+        public OpenHelper(Context context, int flags) {
+            super(context,
+                  flags == FLAG_DATABASE_IN_MEMORY ? null : DATABASE_NAME,
+                  null,
+                  DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL(QUERY_CREATE_DOCUMENTS);
+            db.execSQL(QUERY_CREATE_ROOT_EXTRA);
+            db.execSQL(QUERY_CREATE_VIEW_ROOTS);
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @VisibleForTesting
+    static void deleteDatabase(Context context) {
+        context.deleteDatabase(DATABASE_NAME);
     }
 
     /**
@@ -335,8 +390,7 @@
      * @param resources Resources used to get localized root name.
      * @param root Root to be converted {@link ContentValues}.
      */
-    private static void getRootDocumentValues(
-            ContentValues values, Resources resources, MtpRoot root) {
+    static void getRootDocumentValues(ContentValues values, Resources resources, MtpRoot root) {
         values.clear();
         values.put(COLUMN_DEVICE_ID, root.mDeviceId);
         values.put(COLUMN_STORAGE_ID, root.mStorageId);
@@ -360,10 +414,12 @@
      * @param parentId Parent document ID of the object.
      * @param info MTP object info.
      */
-    private void getChildDocumentValues(
+    static void getChildDocumentValues(
             ContentValues values, int deviceId, String parentId, MtpObjectInfo info) {
         values.clear();
-        final String mimeType = CursorHelper.formatTypeToMimeType(info.getFormat());
+        final String mimeType = info.getFormat() == MtpConstants.FORMAT_ASSOCIATION ?
+                DocumentsContract.Document.MIME_TYPE_DIR :
+                MediaFile.getMimeTypeForFormatCode(info.getFormat());
         int flag = 0;
         if (info.getProtectionStatus() == 0) {
             flag |= Document.FLAG_SUPPORTS_DELETE |
@@ -391,19 +447,11 @@
         values.put(Document.COLUMN_SIZE, info.getCompressedSize());
     }
 
-    /**
-     * @param deviceId Device ID.
-     * @return Key for {@link #mMappingMode}.
-     */
-    private static String getRootDocumentsMappingStateKey(int deviceId) {
-        return "RootDocuments/" + deviceId;
-    }
-
-    /**
-     * @param parentDocumentId Document ID for the parent document.
-     * @return Key for {@link #mMappingMode}.
-     */
-    private static String getChildDocumentsMappingStateKey(String parentDocumentId) {
-        return "ChildDocuments/" + parentDocumentId;
+    static String[] strings(Object... args) {
+        final String[] results = new String[args.length];
+        for (int i = 0; i < args.length; i++) {
+            results[i] = Objects.toString(args[i]);
+        }
+        return results;
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
index 97c1d29..0ead2d5 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
@@ -24,7 +24,7 @@
  */
 class MtpDatabaseConstants {
     static final int DATABASE_VERSION = 1;
-    static final String DATABASE_NAME = null;
+    static final String DATABASE_NAME = "database";
 
     static final int FLAG_DATABASE_IN_MEMORY = 1;
     static final int FLAG_DATABASE_IN_FILE = 0;
@@ -129,11 +129,7 @@
                             Root.COLUMN_TITLE + "," +
                     TABLE_DOCUMENTS + "." + Document.COLUMN_SUMMARY + " AS " +
                             Root.COLUMN_SUMMARY + "," +
-                    // Temporary replace COLUMN_DOCUMENT_ID with old format.
                     TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID + " AS " +
-                    Root.COLUMN_DOCUMENT_ID + "_," +
-                    TABLE_DOCUMENTS + "." + COLUMN_DEVICE_ID + "|| '_' ||" +
-                    TABLE_DOCUMENTS + "." + COLUMN_STORAGE_ID + "||'_0' AS " +
                     Root.COLUMN_DOCUMENT_ID + "," +
                     TABLE_ROOT_EXTRA + "." + Root.COLUMN_AVAILABLE_BYTES + "," +
                     TABLE_ROOT_EXTRA + "." + Root.COLUMN_CAPACITY_BYTES + "," +
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseInternal.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseInternal.java
deleted file mode 100644
index 9c5d6b6..0000000
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseInternal.java
+++ /dev/null
@@ -1,515 +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.mtp;
-
-import static com.android.mtp.MtpDatabaseConstants.*;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract.Root;
-
-import java.util.Objects;
-
-/**
- * Class that provides operations processing SQLite database directly.
- */
-class MtpDatabaseInternal {
-    private static class OpenHelper extends SQLiteOpenHelper {
-        public OpenHelper(Context context, int flags) {
-            super(context,
-                  flags == FLAG_DATABASE_IN_MEMORY ? null : DATABASE_NAME,
-                  null,
-                  DATABASE_VERSION);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL(QUERY_CREATE_DOCUMENTS);
-            db.execSQL(QUERY_CREATE_ROOT_EXTRA);
-            db.execSQL(QUERY_CREATE_VIEW_ROOTS);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    private final SQLiteDatabase mDatabase;
-
-    MtpDatabaseInternal(Context context, int flags) {
-        final OpenHelper helper = new OpenHelper(context, flags);
-        mDatabase = helper.getWritableDatabase();
-    }
-
-    void close() {
-        mDatabase.close();
-    }
-
-    /**
-     * Queries roots information.
-     * @param columnNames Column names defined in {@link android.provider.DocumentsContract.Root}.
-     * @return Database cursor.
-     */
-    Cursor queryRoots(String[] columnNames) {
-        return mDatabase.query(
-                VIEW_ROOTS,
-                columnNames,
-                COLUMN_ROW_STATE + " IN (?, ?)",
-                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED),
-                null,
-                null,
-                null);
-    }
-
-    /**
-     * Queries root documents information.
-     * @param columnNames Column names defined in
-     *     {@link android.provider.DocumentsContract.Document}.
-     * @return Database cursor.
-     */
-    Cursor queryRootDocuments(String[] columnNames) {
-        return mDatabase.query(
-                TABLE_DOCUMENTS,
-                columnNames,
-                COLUMN_ROW_STATE + " IN (?, ?)",
-                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED),
-                null,
-                null,
-                null);
-    }
-
-    /**
-     * Queries documents information.
-     * @param columnNames Column names defined in
-     *     {@link android.provider.DocumentsContract.Document}.
-     * @return Database cursor.
-     */
-    Cursor queryChildDocuments(String[] columnNames, String parentDocumentId) {
-        return mDatabase.query(
-                TABLE_DOCUMENTS,
-                columnNames,
-                COLUMN_ROW_STATE + " IN (?, ?) AND " + COLUMN_PARENT_DOCUMENT_ID + " = ?",
-                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED, parentDocumentId),
-                null,
-                null,
-                null);
-    }
-
-    /**
-     * Remove all rows belong to a device.
-     * @param deviceId Device ID.
-     */
-    void removeDeviceRows(int deviceId) {
-        deleteDocumentsAndRoots(COLUMN_DEVICE_ID + "=?", strings(deviceId));
-    }
-
-    /**
-     * Gets identifier from document ID.
-     * @param documentId Document ID.
-     * @return Identifier.
-     */
-    Identifier createIdentifier(String documentId) {
-        // Currently documentId is old format.
-        final Identifier oldIdentifier = Identifier.createFromDocumentId(documentId);
-        final String selection;
-        final String[] args;
-        if (oldIdentifier.mObjectHandle == CursorHelper.DUMMY_HANDLE_FOR_ROOT) {
-            selection = COLUMN_DEVICE_ID + "= ? AND " +
-                    COLUMN_ROW_STATE + " IN (?, ?) AND " +
-                    COLUMN_STORAGE_ID + "= ? AND " +
-                    COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
-            args = strings(
-                    oldIdentifier.mDeviceId,
-                    ROW_STATE_VALID,
-                    ROW_STATE_INVALIDATED,
-                    oldIdentifier.mStorageId);
-        } else {
-            selection = COLUMN_DEVICE_ID + "= ? AND " +
-                    COLUMN_ROW_STATE + " IN (?, ?) AND " +
-                    COLUMN_STORAGE_ID + "= ? AND " +
-                    COLUMN_OBJECT_HANDLE + " = ?";
-            args = strings(
-                    oldIdentifier.mDeviceId,
-                    ROW_STATE_VALID,
-                    ROW_STATE_INVALIDATED,
-                    oldIdentifier.mStorageId,
-                    oldIdentifier.mObjectHandle);
-        }
-
-        final Cursor cursor = mDatabase.query(
-                TABLE_DOCUMENTS,
-                strings(Document.COLUMN_DOCUMENT_ID),
-                selection,
-                args,
-                null,
-                null,
-                null,
-                "1");
-        try {
-            if (cursor.getCount() == 0) {
-                return oldIdentifier;
-            } else {
-                cursor.moveToNext();
-                return new Identifier(
-                        oldIdentifier.mDeviceId,
-                        oldIdentifier.mStorageId,
-                        oldIdentifier.mObjectHandle,
-                        cursor.getString(0));
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Starts adding new documents.
-     * The methods decides mapping mode depends on if all documents under the given parent have MTP
-     * identifier or not. If all the documents have MTP identifier, it uses the identifier to find
-     * a corresponding existing row. Otherwise it does heuristic.
-     *
-     * @param selection Query matches valid documents.
-     * @param arg Argument for selection.
-     * @return Mapping mode.
-     */
-    int startAddingDocuments(String selection, String arg) {
-        mDatabase.beginTransaction();
-        try {
-            // Delete all pending rows.
-            deleteDocumentsAndRoots(
-                    selection + " AND " + COLUMN_ROW_STATE + "=?", strings(arg, ROW_STATE_PENDING));
-
-            // Set all documents as invalidated.
-            final ContentValues values = new ContentValues();
-            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
-            mDatabase.update(TABLE_DOCUMENTS, values, selection, new String[] { arg });
-
-            // If we have rows that does not have MTP identifier, do heuristic mapping by name.
-            final boolean useNameForResolving = DatabaseUtils.queryNumEntries(
-                    mDatabase,
-                    TABLE_DOCUMENTS,
-                    selection + " AND " + COLUMN_STORAGE_ID + " IS NULL",
-                    new String[] { arg }) > 0;
-            mDatabase.setTransactionSuccessful();
-            return useNameForResolving ? MAP_BY_NAME : MAP_BY_MTP_IDENTIFIER;
-        } finally {
-            mDatabase.endTransaction();
-        }
-    }
-
-    /**
-     * Puts the documents into the database.
-     * If the mapping mode is not heuristic, it just adds the rows to the database or updates the
-     * existing rows with the new values. If the mapping mode is heuristic, it adds some new rows as
-     * 'pending' state when that rows may be corresponding to existing 'invalidated' rows. Then
-     * {@link #stopAddingDocuments(String, String, String)} turns the pending rows into 'valid'
-     * rows. If the methods adds rows to database, it updates valueList with correct document ID.
-     *
-     * @param valuesList Values for documents to be stored in the database.
-     * @param selection SQL where closure to select rows that shares the same parent.
-     * @param arg Argument for selection SQL.
-     * @param heuristic Whether the mapping mode is heuristic.
-     * @return Whether the method adds new rows.
-     */
-    boolean putDocuments(
-            ContentValues[] valuesList,
-            String selection,
-            String arg,
-            boolean heuristic,
-            String mappingKey) {
-        boolean added = false;
-        mDatabase.beginTransaction();
-        try {
-            for (final ContentValues values : valuesList) {
-                final Cursor candidateCursor = mDatabase.query(
-                        TABLE_DOCUMENTS,
-                        strings(Document.COLUMN_DOCUMENT_ID),
-                        selection + " AND " +
-                        COLUMN_ROW_STATE + "=? AND " +
-                        mappingKey + "=?",
-                        strings(arg, ROW_STATE_INVALIDATED, values.getAsString(mappingKey)),
-                        null,
-                        null,
-                        null,
-                        "1");
-                try {
-                    final long rowId;
-                    if (candidateCursor.getCount() == 0) {
-                        rowId = mDatabase.insert(TABLE_DOCUMENTS, null, values);
-                        if (rowId == -1) {
-                            throw new SQLiteException("Failed to put a document into database.");
-                        }
-                        added = true;
-                    } else if (!heuristic) {
-                        candidateCursor.moveToNext();
-                        final String documentId = candidateCursor.getString(0);
-                        rowId = mDatabase.update(
-                                TABLE_DOCUMENTS,
-                                values,
-                                SELECTION_DOCUMENT_ID,
-                                strings(documentId));
-                    } else {
-                        values.put(COLUMN_ROW_STATE, ROW_STATE_PENDING);
-                        rowId = mDatabase.insert(TABLE_DOCUMENTS, null, values);
-                    }
-                    // Document ID is a primary integer key of the table. So the returned row
-                    // IDs should be same with the document ID.
-                    values.put(Document.COLUMN_DOCUMENT_ID, rowId);
-                } finally {
-                    candidateCursor.close();
-                }
-            }
-
-            mDatabase.setTransactionSuccessful();
-            return added;
-        } finally {
-            mDatabase.endTransaction();
-        }
-    }
-
-    /**
-     * Puts extra information for root documents.
-     * @param values Values containing extra information.
-     */
-    void putRootExtra(ContentValues values) {
-        mDatabase.replace(TABLE_ROOT_EXTRA, null, values);
-    }
-
-    /**
-     * Maps 'pending' document and 'invalidated' document that shares the same column of groupKey.
-     * If the database does not find corresponding 'invalidated' document, it just removes
-     * 'invalidated' document from the database.
-     * @param selection Query to select rows for resolving.
-     * @param arg Argument for selection SQL.
-     * @param groupKey Column name used to find corresponding rows.
-     * @return Whether the methods adds or removed visible rows.
-     */
-    boolean stopAddingDocuments(String selection, String arg, String groupKey) {
-        mDatabase.beginTransaction();
-        try {
-            // Get 1-to-1 mapping of invalidated document and pending document.
-            final String invalidatedIdQuery = createStateFilter(
-                    ROW_STATE_INVALIDATED, Document.COLUMN_DOCUMENT_ID);
-            final String pendingIdQuery = createStateFilter(
-                    ROW_STATE_PENDING, Document.COLUMN_DOCUMENT_ID);
-            // SQL should be like:
-            // SELECT group_concat(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END),
-            //        group_concat(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END)
-            // WHERE device_id = ? AND parent_document_id IS NULL
-            // GROUP BY display_name
-            // HAVING count(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END) = 1 AND
-            //        count(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END) = 1
-            final Cursor mergingCursor = mDatabase.query(
-                    TABLE_DOCUMENTS,
-                    new String[] {
-                            "group_concat(" + invalidatedIdQuery + ")",
-                            "group_concat(" + pendingIdQuery + ")"
-                    },
-                    selection,
-                    strings(arg),
-                    groupKey,
-                    "count(" + invalidatedIdQuery + ") = 1 AND count(" + pendingIdQuery + ") = 1",
-                    null);
-
-            final ContentValues values = new ContentValues();
-            while (mergingCursor.moveToNext()) {
-                final String invalidatedId = mergingCursor.getString(0);
-                final String pendingId = mergingCursor.getString(1);
-
-                // Obtain the new values including the latest object handle from mapping row.
-                getFirstRow(
-                        TABLE_DOCUMENTS,
-                        SELECTION_DOCUMENT_ID,
-                        new String[] { pendingId },
-                        values);
-                values.remove(Document.COLUMN_DOCUMENT_ID);
-                values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
-                mDatabase.update(
-                        TABLE_DOCUMENTS,
-                        values,
-                        SELECTION_DOCUMENT_ID,
-                        new String[] { invalidatedId });
-
-                getFirstRow(
-                        TABLE_ROOT_EXTRA,
-                        SELECTION_ROOT_ID,
-                        new String[] { pendingId },
-                        values);
-                if (values.size() > 0) {
-                    values.remove(Root.COLUMN_ROOT_ID);
-                    mDatabase.update(
-                            TABLE_ROOT_EXTRA,
-                            values,
-                            SELECTION_ROOT_ID,
-                            new String[] { invalidatedId });
-                }
-
-                // Delete 'pending' row.
-                deleteDocumentsAndRoots(SELECTION_DOCUMENT_ID, new String[] { pendingId });
-            }
-            mergingCursor.close();
-
-            boolean changed = false;
-
-            // Delete all invalidated rows that cannot be mapped.
-            if (deleteDocumentsAndRoots(
-                    COLUMN_ROW_STATE + " = ? AND " + selection,
-                    strings(ROW_STATE_INVALIDATED, arg))) {
-                changed = true;
-            }
-
-            // The database cannot find old document ID for the pending rows.
-            // Turn the all pending rows into valid state, which means the rows become to be
-            // valid with new document ID.
-            values.clear();
-            values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
-            if (mDatabase.update(
-                    TABLE_DOCUMENTS,
-                    values,
-                    COLUMN_ROW_STATE + " = ? AND " + selection,
-                    strings(ROW_STATE_PENDING, arg)) != 0) {
-                changed = true;
-            }
-            mDatabase.setTransactionSuccessful();
-            return changed;
-        } finally {
-            mDatabase.endTransaction();
-        }
-    }
-
-    /**
-     * Clears MTP related identifier.
-     * It clears MTP's object handle and storage ID that are not stable over MTP sessions and mark
-     * the all documents as 'invalidated'. It also remove 'pending' rows as adding is cancelled
-     * now.
-     */
-    void clearMapping() {
-        mDatabase.beginTransaction();
-        try {
-            deleteDocumentsAndRoots(COLUMN_ROW_STATE + " = ?", strings(ROW_STATE_PENDING));
-            final ContentValues values = new ContentValues();
-            values.putNull(COLUMN_OBJECT_HANDLE);
-            values.putNull(COLUMN_STORAGE_ID);
-            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
-            mDatabase.update(TABLE_DOCUMENTS, values, null, null);
-            mDatabase.setTransactionSuccessful();
-        } finally {
-            mDatabase.endTransaction();
-        }
-    }
-
-    /**
-     * {@link android.database.sqlite.SQLiteDatabase#beginTransaction()}
-     */
-    void beginTransaction() {
-        mDatabase.beginTransaction();
-    }
-
-    /**
-     * {@link android.database.sqlite.SQLiteDatabase#setTransactionSuccessful()}
-     */
-    void setTransactionSuccessful() {
-        mDatabase.setTransactionSuccessful();
-    }
-
-    /**
-     * {@link android.database.sqlite.SQLiteDatabase#endTransaction()}
-     */
-    void endTransaction() {
-        mDatabase.endTransaction();
-    }
-
-    /**
-     * Deletes a document, and its root information if the document is a root document.
-     * @param selection Query to select documents.
-     * @param args Arguments for selection.
-     * @return Whether the method deletes rows.
-     */
-    private boolean deleteDocumentsAndRoots(String selection, String[] args) {
-        mDatabase.beginTransaction();
-        try {
-            int deleted = 0;
-            deleted += mDatabase.delete(
-                    TABLE_ROOT_EXTRA,
-                    Root.COLUMN_ROOT_ID + " IN (" + SQLiteQueryBuilder.buildQueryString(
-                            false,
-                            TABLE_DOCUMENTS,
-                            new String[] { Document.COLUMN_DOCUMENT_ID },
-                            selection,
-                            null,
-                            null,
-                            null,
-                            null) + ")",
-                    args);
-            deleted += mDatabase.delete(TABLE_DOCUMENTS, selection, args);
-            mDatabase.setTransactionSuccessful();
-            return deleted != 0;
-        } finally {
-            mDatabase.endTransaction();
-        }
-    }
-
-    /**
-     * Obtains values of the first row for the query.
-     * @param values ContentValues that the values are stored to.
-     * @param table Target table.
-     * @param selection Query to select rows.
-     * @param args Argument for query.
-     */
-    private void getFirstRow(String table, String selection, String[] args, ContentValues values) {
-        values.clear();
-        final Cursor cursor = mDatabase.query(table, null, selection, args, null, null, null, "1");
-        if (cursor.getCount() == 0) {
-            return;
-        }
-        cursor.moveToNext();
-        DatabaseUtils.cursorRowToContentValues(cursor, values);
-        cursor.close();
-    }
-
-    /**
-     * Gets SQL expression that represents the given value or NULL depends on the row state.
-     * @param state Expected row state.
-     * @param a SQL value.
-     * @return Expression that represents a if the row state is expected one, and represents NULL
-     *     otherwise.
-     */
-    private static String createStateFilter(int state, String a) {
-        return "CASE WHEN " + COLUMN_ROW_STATE + " = " + Integer.toString(state) +
-                " THEN " + a + " ELSE NULL END";
-    }
-
-    /**
-     * Converts values into string array.
-     * @param args Values converted into string array.
-     * @return String array.
-     */
-    private static String[] strings(Object... args) {
-        final String[] results = new String[args.length];
-        for (int i = 0; i < args.length; i++) {
-            results[i] = Objects.toString(args[i]);
-        }
-        return results;
-    }
-}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 7c0676f..9511e15 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -20,8 +20,9 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.database.MatrixCursor;
 import android.graphics.Point;
+import android.media.MediaFile;
+import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
@@ -56,11 +57,13 @@
             Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
     };
 
+    private final Object mDeviceListLock = new Object();
+
     private static MtpDocumentsProvider sSingleton;
 
     private MtpManager mMtpManager;
     private ContentResolver mResolver;
-    @GuardedBy("mDeviceToolkits")
+    @GuardedBy("mDeviceListLock")
     private Map<Integer, DeviceToolkit> mDeviceToolkits;
     private RootScanner mRootScanner;
     private Resources mResources;
@@ -82,6 +85,7 @@
         mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
         mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_FILE);
         mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
+        resume();
         return true;
     }
 
@@ -97,6 +101,7 @@
         mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
         mDatabase = database;
         mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
+        resume();
     }
 
     @Override
@@ -116,39 +121,7 @@
         if (projection == null) {
             projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION;
         }
-        final Identifier identifier = Identifier.createFromDocumentId(documentId);
-
-        if (identifier.mObjectHandle != CursorHelper.DUMMY_HANDLE_FOR_ROOT) {
-            MtpObjectInfo objectInfo;
-            try {
-                objectInfo = mMtpManager.getObjectInfo(
-                        identifier.mDeviceId, identifier.mObjectHandle);
-            } catch (IOException e) {
-                throw new FileNotFoundException(e.getMessage());
-            }
-            final MatrixCursor cursor = new MatrixCursor(projection);
-            CursorHelper.addToCursor(
-                    objectInfo,
-                    new Identifier(identifier.mDeviceId, identifier.mStorageId),
-                    cursor.newRow());
-            return cursor;
-        } else {
-            MtpRoot[] roots;
-            try {
-                roots = mMtpManager.getRoots(identifier.mDeviceId);
-            } catch (IOException e) {
-                throw new FileNotFoundException(e.getMessage());
-            }
-            for (final MtpRoot root : roots) {
-                if (identifier.mStorageId != root.mStorageId)
-                    continue;
-                final MatrixCursor cursor = new MatrixCursor(projection);
-                CursorHelper.addToCursor(mResources, root, cursor.newRow());
-                return cursor;
-            }
-        }
-
-        throw new FileNotFoundException();
+        return mDatabase.queryDocument(documentId, projection);
     }
 
     @Override
@@ -170,7 +143,7 @@
     public ParcelFileDescriptor openDocument(
             String documentId, String mode, CancellationSignal signal)
                     throws FileNotFoundException {
-        final Identifier identifier = Identifier.createFromDocumentId(documentId);
+        final Identifier identifier = mDatabase.createIdentifier(documentId);
         try {
             switch (mode) {
                 case "r":
@@ -195,7 +168,7 @@
             String documentId,
             Point sizeHint,
             CancellationSignal signal) throws FileNotFoundException {
-        final Identifier identifier = Identifier.createFromDocumentId(documentId);
+        final Identifier identifier = mDatabase.createIdentifier(documentId);
         try {
             return new AssetFileDescriptor(
                     getPipeManager(identifier).readThumbnail(mMtpManager, identifier),
@@ -209,22 +182,24 @@
     @Override
     public void deleteDocument(String documentId) throws FileNotFoundException {
         try {
-            final Identifier identifier = Identifier.createFromDocumentId(documentId);
-            final int parentHandle =
-                    mMtpManager.getParent(identifier.mDeviceId, identifier.mObjectHandle);
+            final Identifier identifier = mDatabase.createIdentifier(documentId);
+            final Identifier parentIdentifier =
+                    mDatabase.createIdentifier(mDatabase.getParentId(documentId));
             mMtpManager.deleteDocument(identifier.mDeviceId, identifier.mObjectHandle);
-            final Identifier parentIdentifier = new Identifier(
-                    identifier.mDeviceId, identifier.mStorageId, parentHandle);
+            mDatabase.deleteDocument(documentId);
             getDocumentLoader(parentIdentifier).clearTask(parentIdentifier);
-            notifyChildDocumentsChange(parentIdentifier.toDocumentId());
+            notifyChildDocumentsChange(parentIdentifier.mDocumentId);
         } catch (IOException error) {
+            for (final StackTraceElement element : error.getStackTrace()) {
+                Log.e("hirono", element.toString());
+            }
             throw new FileNotFoundException(error.getMessage());
         }
     }
 
     @Override
     public void onTrimMemory(int level) {
-        synchronized (mDeviceToolkits) {
+        synchronized (mDeviceListLock) {
             for (final DeviceToolkit toolkit : mDeviceToolkits.values()) {
                 toolkit.mDocumentLoader.clearCompletedTasks();
             }
@@ -235,19 +210,23 @@
     public String createDocument(String parentDocumentId, String mimeType, String displayName)
             throws FileNotFoundException {
         try {
-            final Identifier parentId = Identifier.createFromDocumentId(parentDocumentId);
+            final Identifier parentId = mDatabase.createIdentifier(parentDocumentId);
             final ParcelFileDescriptor pipe[] = ParcelFileDescriptor.createReliablePipe();
             pipe[0].close();  // 0 bytes for a new document.
-            final int objectHandle = mMtpManager.createDocument(
-                    parentId.mDeviceId,
-                    new MtpObjectInfo.Builder()
-                            .setStorageId(parentId.mStorageId)
-                            .setParent(parentId.mObjectHandle)
-                            .setFormat(CursorHelper.mimeTypeToFormatType(displayName, mimeType))
-                            .setName(displayName)
-                            .build(), pipe[1]);
-            final String documentId = new Identifier(parentId.mDeviceId, parentId.mStorageId,
-                   objectHandle).toDocumentId();
+            final int formatCode = Document.MIME_TYPE_DIR.equals(mimeType) ?
+                    MtpConstants.FORMAT_ASSOCIATION :
+                    MediaFile.getFormatCode(displayName, mimeType);
+            final MtpObjectInfo info = new MtpObjectInfo.Builder()
+                    .setStorageId(parentId.mStorageId)
+                    .setParent(parentId.mObjectHandle)
+                    .setFormat(formatCode)
+                    .setName(displayName)
+                    .build();
+            final int objectHandle = mMtpManager.createDocument(parentId.mDeviceId, info, pipe[1]);
+            final MtpObjectInfo infoWithHandle =
+                    new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build();
+            final String documentId = mDatabase.putNewDocument(
+                    parentId.mDeviceId, parentDocumentId, infoWithHandle);
             getDocumentLoader(parentId).clearTask(parentId);
             notifyChildDocumentsChange(parentDocumentId);
             return documentId;
@@ -258,47 +237,26 @@
     }
 
     void openDevice(int deviceId) throws IOException {
-        synchronized (mDeviceToolkits) {
+        synchronized (mDeviceListLock) {
             mMtpManager.openDevice(deviceId);
-            mDeviceToolkits.put(deviceId, new DeviceToolkit(mMtpManager, mResolver, mDatabase));
+            mDeviceToolkits.put(
+                    deviceId, new DeviceToolkit(mMtpManager, mResolver, mDatabase));
         }
         mRootScanner.resume();
     }
 
     void closeDevice(int deviceId) throws IOException, InterruptedException {
-        // TODO: Flush the device before closing (if not closed externally).
-        synchronized (mDeviceToolkits) {
-            getDeviceToolkit(deviceId).mDocumentLoader.clearTasks();
-            mDeviceToolkits.remove(deviceId);
+        synchronized (mDeviceListLock) {
+            closeDeviceInternal(deviceId);
             mDatabase.removeDeviceRows(deviceId);
-            mMtpManager.closeDevice(deviceId);
         }
         mRootScanner.notifyChange();
-        if (!hasOpenedDevices()) {
-            mRootScanner.pause();
-        }
-    }
-
-    synchronized void closeAllDevices() throws InterruptedException {
-        boolean closed = false;
-        for (int deviceId : mMtpManager.getOpenedDeviceIds()) {
-            try {
-                mDatabase.removeDeviceRows(deviceId);
-                mMtpManager.closeDevice(deviceId);
-                getDeviceToolkit(deviceId).mDocumentLoader.clearTasks();
-                closed = true;
-            } catch (IOException d) {
-                Log.d(TAG, "Failed to close the MTP device: " + deviceId);
-            }
-        }
-        if (closed) {
-            mRootScanner.notifyChange();
-            mRootScanner.pause();
-        }
     }
 
     boolean hasOpenedDevices() {
-        return mMtpManager.getOpenedDeviceIds().length != 0;
+        synchronized (mDeviceListLock) {
+            return mMtpManager.getOpenedDeviceIds().length != 0;
+        }
     }
 
     /**
@@ -306,14 +264,18 @@
      */
     @Override
     public void shutdown() {
-        try {
-            closeAllDevices();
-        } catch (InterruptedException e) {
-            // It should fail unit tests by throwing runtime exception.
-            throw new RuntimeException(e.getMessage());
-        } finally {
-            mDatabase.close();
-            super.shutdown();
+        synchronized (mDeviceListLock) {
+            try {
+                for (final int id : mMtpManager.getOpenedDeviceIds()) {
+                    closeDeviceInternal(id);
+                }
+            } catch (InterruptedException|IOException e) {
+                // It should fail unit tests by throwing runtime exception.
+                throw new RuntimeException(e);
+            } finally {
+                mDatabase.close();
+                super.shutdown();
+            }
         }
     }
 
@@ -324,8 +286,35 @@
                 false);
     }
 
+    /**
+     * Reopens MTP devices based on database state.
+     */
+    private void resume() {
+        synchronized (mDeviceListLock) {
+            mDatabase.getMapper().clearMapping();
+            final int[] ids = mDatabase.getDeviceIds();
+            for (final int id : ids) {
+                try {
+                    openDevice(id);
+                } catch (IOException exception) {
+                    mDatabase.removeDeviceRows(id);
+                }
+            }
+        }
+    }
+
+    private void closeDeviceInternal(int deviceId) throws IOException, InterruptedException {
+        // TODO: Flush the device before closing (if not closed externally).
+        getDeviceToolkit(deviceId).mDocumentLoader.clearTasks();
+        mDeviceToolkits.remove(deviceId);
+        mMtpManager.closeDevice(deviceId);
+        if (!hasOpenedDevices()) {
+            mRootScanner.pause();
+        }
+    }
+
     private DeviceToolkit getDeviceToolkit(int deviceId) throws FileNotFoundException {
-        synchronized (mDeviceToolkits) {
+        synchronized (mDeviceListLock) {
             final DeviceToolkit toolkit = mDeviceToolkits.get(deviceId);
             if (toolkit == null) {
                 throw new FileNotFoundException();
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
index 723dc14..9b3c20f 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
@@ -55,22 +55,20 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        if (intent == null) {
-            // If intent is null, the service was restarted.
-            // TODO: Recover opened devices here.
-            return START_STICKY;
-        }
-        if (intent.getAction().equals(ACTION_OPEN_DEVICE)) {
-            final UsbDevice device = intent.<UsbDevice>getParcelableExtra(EXTRA_DEVICE);
-            try {
-                final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
-                provider.openDevice(device.getDeviceId());
-                return START_STICKY;
-            } catch (IOException error) {
-                Log.e(MtpDocumentsProvider.TAG, error.getMessage());
+        // If intent is null, the service was restarted.
+        if (intent != null) {
+            if (intent.getAction().equals(ACTION_OPEN_DEVICE)) {
+                final UsbDevice device = intent.<UsbDevice>getParcelableExtra(EXTRA_DEVICE);
+                try {
+                    final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
+                    provider.openDevice(device.getDeviceId());
+                    return START_STICKY;
+                } catch (IOException error) {
+                    Log.e(MtpDocumentsProvider.TAG, error.getMessage());
+                }
+            } else {
+                Log.e(MtpDocumentsProvider.TAG, "Received unknown intent action.");
             }
-        } else {
-            Log.w(MtpDocumentsProvider.TAG, "Received unknown intent action.");
         }
         stopSelfIfNeeded();
         return Service.START_NOT_STICKY;
@@ -78,14 +76,8 @@
 
     @Override
     public void onDestroy() {
-        final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
         unregisterReceiver(mReceiver);
         mReceiver = null;
-        try {
-            provider.closeAllDevices();
-        } catch (InterruptedException e) {
-            Log.e(MtpDocumentsProvider.TAG, e.getMessage());
-        }
         super.onDestroy();
     }
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 714936d..cd52f31 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -32,6 +32,7 @@
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.ArrayList;
 
 /**
  * The model wrapping android.mtp API.
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
index affaebd..16523bc 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
@@ -22,10 +22,8 @@
 import android.util.Log;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
index b0962dd..df2ab01 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
@@ -113,13 +113,14 @@
                 for (int deviceId : deviceIds) {
                     try {
                         final MtpRoot[] roots = mManager.getRoots(deviceId);
-                        mDatabase.startAddingRootDocuments(deviceId);
+                        mDatabase.getMapper().startAddingRootDocuments(deviceId);
                         try {
-                            if (mDatabase.putRootDocuments(deviceId, mResources, roots)) {
+                            if (mDatabase.getMapper().putRootDocuments(
+                                    deviceId, mResources, roots)) {
                                 changed = true;
                             }
                         } finally {
-                            if (mDatabase.stopAddingRootDocuments(deviceId)) {
+                            if (mDatabase.getMapper().stopAddingRootDocuments(deviceId)) {
                                 changed = true;
                             }
                         }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
index a80eb51..f0b4343 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
@@ -40,11 +40,11 @@
     @Override
     public void setUp() {
         mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, new TestResources(), new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, new TestResources(), new MtpRoot[] {
                 new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "")
         });
-        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
         mManager = new BlockableTestMtpManager(getContext());
         mResolver = new TestContentResolver();
         mLoader = new DocumentLoader(mManager, mResolver, mDatabase);
@@ -57,7 +57,7 @@
 
     public void testBasic() throws Exception {
         final Uri uri = DocumentsContract.buildChildDocumentsUri(
-                MtpDocumentsProvider.AUTHORITY, mParentIdentifier.toDocumentId());
+                MtpDocumentsProvider.AUTHORITY, mParentIdentifier.mDocumentId);
         setUpDocument(mManager, 40);
         mManager.blockDocument(0, 15);
         mManager.blockDocument(0, 35);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index 25dd1c8..6d9193d 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -20,10 +20,15 @@
 import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import java.io.FileNotFoundException;
+
+import static com.android.mtp.MtpDatabase.strings;
+
 @SmallTest
 public class MtpDatabaseTest extends AndroidTestCase {
     private final String[] COLUMN_NAMES = new String[] {
@@ -55,8 +60,8 @@
     }
 
     public void testPutRootDocuments() throws Exception {
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 1, "Device", "Storage", 1000, 2000, ""),
                 new MtpRoot(0, 2, "Device", "Storage", 2000, 4000, ""),
                 new MtpRoot(0, 3, "Device", "/@#%&<>Storage", 3000, 6000,"")
@@ -97,7 +102,7 @@
                     Root.COLUMN_ICON,
                     Root.COLUMN_TITLE,
                     Root.COLUMN_SUMMARY,
-                    Root.COLUMN_DOCUMENT_ID + "_",
+                    Root.COLUMN_DOCUMENT_ID,
                     Root.COLUMN_AVAILABLE_BYTES,
                     Root.COLUMN_CAPACITY_BYTES
             });
@@ -147,8 +152,8 @@
     }
 
     public void testPutChildDocuments() throws Exception {
-        mDatabase.startAddingChildDocuments("parentId");
-        mDatabase.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.getMapper().startAddingChildDocuments("parentId");
+        mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
@@ -222,8 +227,8 @@
                 Root.COLUMN_AVAILABLE_BYTES
         };
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage A", 1000, 0, ""),
                 new MtpRoot(0, 101, "Device", "Storage B", 1001, 0, "")
         });
@@ -254,7 +259,7 @@
             cursor.close();
         }
 
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
@@ -282,8 +287,8 @@
             cursor.close();
         }
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 200, "Device", "Storage A", 2000, 0, ""),
                 new MtpRoot(0, 202, "Device", "Storage C", 2002, 0, "")
         });
@@ -321,7 +326,7 @@
             cursor.close();
         }
 
-        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
@@ -356,13 +361,13 @@
                 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        mDatabase.startAddingChildDocuments("parentId");
-        mDatabase.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.getMapper().startAddingChildDocuments("parentId");
+        mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
         });
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
         {
             final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
@@ -386,8 +391,8 @@
             cursor.close();
         }
 
-        mDatabase.startAddingChildDocuments("parentId");
-        mDatabase.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.getMapper().startAddingChildDocuments("parentId");
+        mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
         });
@@ -404,7 +409,7 @@
             cursor.close();
         }
 
-        mDatabase.stopAddingChildDocuments("parentId");
+        mDatabase.getMapper().stopAddingChildDocuments("parentId");
 
         {
             final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
@@ -433,12 +438,12 @@
                 Root.COLUMN_ROOT_ID,
                 Root.COLUMN_AVAILABLE_BYTES
         };
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.startAddingRootDocuments(1);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().startAddingRootDocuments(1);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage", 0, 0, "")
         });
-        mDatabase.putRootDocuments(1, resources, new MtpRoot[] {
+        mDatabase.getMapper().putRootDocuments(1, resources, new MtpRoot[] {
                 new MtpRoot(1, 100, "Device", "Storage", 0, 0, "")
         });
 
@@ -468,18 +473,18 @@
             cursor.close();
         }
 
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.startAddingRootDocuments(1);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().startAddingRootDocuments(1);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 200, "Device", "Storage", 2000, 0, "")
         });
-        mDatabase.putRootDocuments(1, resources, new MtpRoot[] {
+        mDatabase.getMapper().putRootDocuments(1, resources, new MtpRoot[] {
                 new MtpRoot(1, 300, "Device", "Storage", 3000, 0, "")
         });
-        mDatabase.stopAddingRootDocuments(0);
-        mDatabase.stopAddingRootDocuments(1);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(1);
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
@@ -514,25 +519,25 @@
                 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE
         };
 
-        mDatabase.startAddingChildDocuments("parentId1");
-        mDatabase.startAddingChildDocuments("parentId2");
-        mDatabase.putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
+        mDatabase.getMapper().startAddingChildDocuments("parentId1");
+        mDatabase.getMapper().startAddingChildDocuments("parentId2");
+        mDatabase.getMapper().putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
+        mDatabase.getMapper().putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
                 createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
-        mDatabase.startAddingChildDocuments("parentId1");
-        mDatabase.startAddingChildDocuments("parentId2");
-        mDatabase.putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
+        mDatabase.getMapper().startAddingChildDocuments("parentId1");
+        mDatabase.getMapper().startAddingChildDocuments("parentId2");
+        mDatabase.getMapper().putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
+        mDatabase.getMapper().putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
                 createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.stopAddingChildDocuments("parentId1");
+        mDatabase.getMapper().stopAddingChildDocuments("parentId1");
 
         {
             final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId1");
@@ -563,23 +568,23 @@
                 Root.COLUMN_AVAILABLE_BYTES
         };
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage", 0, 0, ""),
         });
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 200, "Device", "Storage", 2000, 0, ""),
         });
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 300, "Device", "Storage", 3000, 0, ""),
         });
-        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
@@ -611,18 +616,18 @@
                 Root.COLUMN_AVAILABLE_BYTES
         };
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage", 0, 0, ""),
         });
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 200, "Device", "Storage", 2000, 0, ""),
                 new MtpRoot(0, 201, "Device", "Storage", 2001, 0, ""),
         });
-        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
@@ -653,17 +658,17 @@
     public void testReplaceExistingRoots() {
         // The client code should be able to replace existing rows with new information.
         // Add one.
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
         });
-        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
         // Replace it.
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage B", 1000, 1000, ""),
         });
-        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.getMapper().stopAddingRootDocuments(0);
         {
             final String[] columns = new String[] {
                     DocumentsContract.Document.COLUMN_DOCUMENT_ID,
@@ -692,26 +697,155 @@
         }
     }
 
-    public void _testFailToReplaceExisitingUnmappedRoots() {
+    public void testFailToReplaceExisitingUnmappedRoots() {
         // The client code should not be able to replace rows before resolving 'unmapped' rows.
         // Add one.
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
         });
-        mDatabase.clearMapping();
+        mDatabase.getMapper().clearMapping();
+        final Cursor oldCursor = mDatabase.queryRoots(strings(Root.COLUMN_ROOT_ID));
+        assertEquals(1, oldCursor.getCount());
+
         // Add one.
-        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 100, "Device", "Storage B", 1000, 1000, ""),
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 101, "Device", "Storage B", 1000, 1000, ""),
         });
         // Add one more before resolving unmapped documents.
-        try {
-            mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
-                    new MtpRoot(0, 100, "Device", "Storage B", 1000, 1000, ""),
-            });
-            fail();
-        } catch (Throwable e) {
-            assertTrue(e instanceof Error);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 102, "Device", "Storage B", 1000, 1000, ""),
+        });
+        mDatabase.getMapper().stopAddingRootDocuments(0);
+
+        // Because the roots shares the same name, the roots should have new IDs.
+        final Cursor newCursor = mDatabase.queryRoots(strings(Root.COLUMN_ROOT_ID));
+        assertEquals(2, newCursor.getCount());
+        oldCursor.moveToNext();
+        newCursor.moveToNext();
+        assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
+        newCursor.moveToNext();
+        assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
+
+        oldCursor.close();
+        newCursor.close();
+    }
+
+    public void testQueryDocument() {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
+        });
+        mDatabase.getMapper().stopAddingRootDocuments(0);
+
+        final Cursor cursor = mDatabase.queryDocument("1", strings(Document.COLUMN_DISPLAY_NAME));
+        assertEquals(1, cursor.getCount());
+        cursor.moveToNext();
+        assertEquals("Device Storage A", cursor.getString(0));
+        cursor.close();
+    }
+
+    public void testGetParentId() throws FileNotFoundException {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
+        });
+        mDatabase.getMapper().stopAddingRootDocuments(0);
+
+        mDatabase.getMapper().startAddingChildDocuments("1");
+        mDatabase.getMapper().putChildDocuments(
+                0,
+                "1",
+                new MtpObjectInfo[] {
+                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+                });
+        mDatabase.getMapper().stopAddingChildDocuments("1");
+
+        assertEquals("1", mDatabase.getParentId("2"));
+    }
+
+    public void testDeleteDocument() {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
+        });
+        mDatabase.getMapper().stopAddingRootDocuments(0);
+
+        mDatabase.getMapper().startAddingChildDocuments("1");
+        mDatabase.getMapper().putChildDocuments(
+                0,
+                "1",
+                new MtpObjectInfo[] {
+                        createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
+                });
+        mDatabase.getMapper().stopAddingChildDocuments("1");
+
+        mDatabase.getMapper().startAddingChildDocuments("2");
+        mDatabase.getMapper().putChildDocuments(
+                0,
+                "2",
+                new MtpObjectInfo[] {
+                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+                });
+        mDatabase.getMapper().stopAddingChildDocuments("2");
+
+        mDatabase.deleteDocument("2");
+
+        {
+            // Do not query deleted documents.
+            final Cursor cursor =
+                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1");
+            assertEquals(0, cursor.getCount());
+            cursor.close();
+        }
+
+        {
+            // Child document should be deleted also.
+            final Cursor cursor =
+                    mDatabase.queryDocument("3", strings(Document.COLUMN_DOCUMENT_ID));
+            assertEquals(0, cursor.getCount());
+            cursor.close();
+        }
+    }
+
+    public void testPutNewDocument() {
+        mDatabase.getMapper().startAddingRootDocuments(0);
+        mDatabase.getMapper().putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
+        });
+        mDatabase.getMapper().stopAddingRootDocuments(0);
+
+        assertEquals(
+                "2",
+                mDatabase.putNewDocument(
+                        0, "1", createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024)));
+
+        {
+            final Cursor cursor =
+                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1");
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("2", cursor.getString(0));
+            cursor.close();
+        }
+
+        // The new document should not be mapped with existing invalidated document.
+        mDatabase.getMapper().clearMapping();
+        mDatabase.getMapper().startAddingChildDocuments("1");
+        mDatabase.putNewDocument(
+                0,
+                "1",
+                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024));
+        mDatabase.getMapper().stopAddingChildDocuments("1");
+
+        {
+            final Cursor cursor =
+                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1");
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("3", cursor.getString(0));
+            cursor.close();
         }
     }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index cabb08d..b20b3bb 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -23,10 +23,14 @@
 import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsContract;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+import static com.android.mtp.MtpDatabase.strings;
 
 @SmallTest
 public class MtpDocumentsProviderTest extends AndroidTestCase {
@@ -42,17 +46,16 @@
     public void setUp() throws IOException {
         mResolver = new TestContentResolver();
         mMtpManager = new TestMtpManager(getContext());
-        mProvider = new MtpDocumentsProvider();
-        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
-        mProvider.onCreateForTesting(mResources, mMtpManager, mResolver, mDatabase);
     }
 
     @Override
     public void tearDown() {
         mProvider.shutdown();
+        MtpDatabase.deleteDatabase(getContext());
     }
 
     public void testOpenAndCloseDevice() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mMtpManager.setRoots(0, new MtpRoot[] {
                 new MtpRoot(
@@ -73,6 +76,7 @@
     }
 
     public void testOpenAndCloseErrorDevice() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         try {
             mProvider.openDevice(1);
             fail();
@@ -104,6 +108,7 @@
     }
 
     public void testQueryRoots() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mMtpManager.addValidDevice(1);
         mMtpManager.setRoots(0, new MtpRoot[] {
@@ -138,7 +143,7 @@
             // TODO: Add storage icon for MTP devices.
             assertTrue(cursor.isNull(2) /* icon */);
             assertEquals("Device A Storage A", cursor.getString(3));
-            assertEquals("0_1_0", cursor.getString(4));
+            assertEquals("1", cursor.getString(4));
             assertEquals(1024, cursor.getInt(5));
         }
 
@@ -154,12 +159,13 @@
             // TODO: Add storage icon for MTP devices.
             assertTrue(cursor.isNull(2) /* icon */);
             assertEquals("Device B Storage B", cursor.getString(3));
-            assertEquals("1_1_0", cursor.getString(4));
+            assertEquals("2", cursor.getString(4));
             assertEquals(2048, cursor.getInt(5));
         }
     }
 
     public void testQueryRoots_error() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mMtpManager.addValidDevice(1);
         // Not set roots for device 0 so that MtpManagerMock#getRoots throws IOException.
@@ -186,29 +192,39 @@
             // TODO: Add storage icon for MTP devices.
             assertTrue(cursor.isNull(2) /* icon */);
             assertEquals("Device B Storage B", cursor.getString(3));
-            assertEquals("1_1_0", cursor.getString(4));
+            assertEquals("1", cursor.getString(4));
             assertEquals(2048, cursor.getInt(5));
         }
     }
 
-    public void testQueryDocument() throws IOException {
+    public void testQueryDocument() throws IOException, InterruptedException, TimeoutException {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
-        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
-                .setObjectHandle(2)
-                .setStorageId(1)
-                .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
-                .setName("image.jpg")
-                .setDateModified(1422716400000L)
-                .setCompressedSize(1024 * 1024 * 5)
-                .setThumbCompressedSize(1024 * 50)
-                .build());
-        final Cursor cursor = mProvider.queryDocument("0_1_2", null);
+
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "") });
+        setupDocuments(
+                0,
+                0,
+                MtpManager.OBJECT_HANDLE_ROOT_CHILDREN,
+                "1",
+                new MtpObjectInfo[] {
+                        new MtpObjectInfo.Builder()
+                                .setObjectHandle(100)
+                                .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
+                                .setName("image.jpg")
+                                .setDateModified(1422716400000L)
+                                .setCompressedSize(1024 * 1024 * 5)
+                                .setThumbCompressedSize(50 * 1024)
+                                .build()
+                });
+
+        final Cursor cursor = mProvider.queryDocument("2", null);
         assertEquals(1, cursor.getCount());
 
         cursor.moveToNext();
 
-        assertEquals("0_1_2", cursor.getString(0));
+        assertEquals("2", cursor.getString(0));
         assertEquals("image/jpeg", cursor.getString(1));
         assertEquals("image.jpg", cursor.getString(2));
         assertEquals(1422716400000L, cursor.getLong(3));
@@ -220,21 +236,33 @@
         assertEquals(1024 * 1024 * 5, cursor.getInt(5));
     }
 
-    public void testQueryDocument_directory() throws IOException {
+    public void testQueryDocument_directory()
+            throws IOException, InterruptedException, TimeoutException {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
-        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
-                .setObjectHandle(2)
-                .setStorageId(1)
-                .setFormat(MtpConstants.FORMAT_ASSOCIATION)
-                .setName("directory")
-                .setDateModified(1422716400000L)
-                .build());
-        final Cursor cursor = mProvider.queryDocument("0_1_2", null);
+
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "") });
+        setupDocuments(
+                0,
+                0,
+                MtpManager.OBJECT_HANDLE_ROOT_CHILDREN,
+                "1",
+                new MtpObjectInfo[] {
+                        new MtpObjectInfo.Builder()
+                                .setObjectHandle(2)
+                                .setStorageId(1)
+                                .setFormat(MtpConstants.FORMAT_ASSOCIATION)
+                                .setName("directory")
+                                .setDateModified(1422716400000L)
+                                .build()
+                });
+
+        final Cursor cursor = mProvider.queryDocument("2", null);
         assertEquals(1, cursor.getCount());
 
         cursor.moveToNext();
-        assertEquals("0_1_2", cursor.getString(0));
+        assertEquals("2", cursor.getString(0));
         assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1));
         assertEquals("directory", cursor.getString(2));
         assertEquals(1422716400000L, cursor.getLong(3));
@@ -246,10 +274,13 @@
         assertEquals(0, cursor.getInt(5));
     }
 
-    public void testQueryDocument_forRoot() throws IOException {
+    public void testQueryDocument_forRoot()
+            throws IOException, InterruptedException, TimeoutException {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
-        mMtpManager.setRoots(0, new MtpRoot[] {
+
+        setupRoots(0, new MtpRoot[] {
                 new MtpRoot(
                         0 /* deviceId */,
                         1 /* storageId */,
@@ -259,11 +290,11 @@
                         4096 /* total space */,
                         "" /* no volume identifier */)
         });
-        final Cursor cursor = mProvider.queryDocument("0_1_0", null);
+        final Cursor cursor = mProvider.queryDocument("1", null);
         assertEquals(1, cursor.getCount());
 
         cursor.moveToNext();
-        assertEquals("0_1_0", cursor.getString(0));
+        assertEquals("1", cursor.getString(0));
         assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1));
         assertEquals("Device A Storage A", cursor.getString(2));
         assertTrue(cursor.isNull(3));
@@ -272,44 +303,47 @@
     }
 
     public void testQueryChildDocuments() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
-        mMtpManager.setObjectHandles(0, 0, -1, new int[] { 1 });
 
-        mDatabase.startAddingRootDocuments(0);
-        mDatabase.putRootDocuments(0, mResources, new MtpRoot[] {
-                new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "")
-        });
-        mDatabase.stopAddingRootDocuments(0);
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "") });
+        setupDocuments(
+                0,
+                0,
+                MtpManager.OBJECT_HANDLE_ROOT_CHILDREN,
+                "1",
+                new MtpObjectInfo[] {
+                        new MtpObjectInfo.Builder()
+                                .setObjectHandle(100)
+                                .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
+                                .setName("image.jpg")
+                                .setCompressedSize(1024 * 1024 * 5)
+                                .setThumbCompressedSize(5 * 1024)
+                                .setProtectionStatus(MtpConstants.PROTECTION_STATUS_READ_ONLY)
+                                .build()
+                });
 
-        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
-                .setObjectHandle(1)
-                .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
-                .setName("image.jpg")
-                .setCompressedSize(1024 * 1024 * 5)
-                .setThumbCompressedSize(5 * 1024)
-                .setProtectionStatus(MtpConstants.PROTECTION_STATUS_READ_ONLY)
-                .build());
-
-        final Cursor cursor = mProvider.queryChildDocuments("0_0_0", null, null);
+        final Cursor cursor = mProvider.queryChildDocuments("1", null, null);
         assertEquals(1, cursor.getCount());
 
         assertTrue(cursor.moveToNext());
-        assertEquals("0_0_1", cursor.getString(0));
+        assertEquals("2", cursor.getString(0));
         assertEquals("image/jpeg", cursor.getString(1));
         assertEquals("image.jpg", cursor.getString(2));
         assertEquals(0, cursor.getLong(3));
         assertEquals(DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL, cursor.getInt(4));
         assertEquals(1024 * 1024 * 5, cursor.getInt(5));
 
-        assertFalse(cursor.moveToNext());
+        cursor.close();
     }
 
     public void testQueryChildDocuments_cursorError() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
         try {
-            mProvider.queryChildDocuments("0_0_0", null, null);
+            mProvider.queryChildDocuments("1", null, null);
             fail();
         } catch (Throwable error) {
             assertTrue(error instanceof FileNotFoundException);
@@ -317,44 +351,134 @@
     }
 
     public void testQueryChildDocuments_documentError() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "") });
         mMtpManager.setObjectHandles(0, 0, -1, new int[] { 1 });
         try {
-            mProvider.queryChildDocuments("0_0_0", null, null);
+            mProvider.queryChildDocuments("1", null, null);
             fail();
         } catch (Throwable error) {
             assertTrue(error instanceof FileNotFoundException);
         }
     }
 
-    public void testDeleteDocument() throws IOException {
+    public void testDeleteDocument() throws IOException, InterruptedException, TimeoutException {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
-        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
-                .setObjectHandle(1)
-                .setParent(2)
-                .build());
-        mProvider.deleteDocument("0_0_1");
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 0, "Device", "Storage", 0, 0, "")
+        });
+        setupDocuments(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, "1", new MtpObjectInfo[] {
+                new MtpObjectInfo.Builder()
+                    .setName("test.txt")
+                    .setObjectHandle(1)
+                    .setParent(-1)
+                    .build()
+        });
+
+        mProvider.deleteDocument("2");
         assertEquals(1, mResolver.getChangeCount(
                 DocumentsContract.buildChildDocumentsUri(
-                        MtpDocumentsProvider.AUTHORITY, "0_0_2")));
+                        MtpDocumentsProvider.AUTHORITY, "1")));
     }
 
-    public void testDeleteDocument_error() throws IOException {
+    public void testDeleteDocument_error()
+            throws IOException, InterruptedException, TimeoutException {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(0);
         mProvider.openDevice(0);
-        mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
-                .setObjectHandle(2)
-                .build());
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 0, "Device", "Storage", 0, 0, "")
+        });
+        setupDocuments(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, "1", new MtpObjectInfo[] {
+                new MtpObjectInfo.Builder()
+                    .setName("test.txt")
+                    .setObjectHandle(1)
+                    .setParent(-1)
+                    .build()
+        });
         try {
-            mProvider.deleteDocument("0_0_1");
+            mProvider.deleteDocument("3");
             fail();
         } catch (Throwable e) {
             assertTrue(e instanceof IOException);
         }
         assertEquals(0, mResolver.getChangeCount(
                 DocumentsContract.buildChildDocumentsUri(
-                        MtpDocumentsProvider.AUTHORITY, "0_0_2")));
+                        MtpDocumentsProvider.AUTHORITY, "1")));
+    }
+
+    @MediumTest
+    public void testPauseAndResume() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_FILE);
+        mMtpManager.addValidDevice(0);
+        mProvider.openDevice(0);
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Device", "Storage", 0, 0, "")});
+
+        {
+            final Cursor cursor = mProvider.queryRoots(
+                    strings(DocumentsContract.Root.COLUMN_ROOT_ID));
+            cursor.moveToNext();
+            assertEquals(1, cursor.getInt(0));
+        }
+
+        mProvider.shutdown();
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_FILE);
+
+        {
+            // We can still fetch roots after relaunching the provider.
+            final Cursor cursor = mProvider.queryRoots(
+                    strings(DocumentsContract.Root.COLUMN_ROOT_ID));
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals(1, cursor.getInt(0));
+            assertEquals(1, mMtpManager.getOpenedDeviceIds().length);
+        }
+    }
+
+    private void setupProvider(int flag) {
+        mDatabase = new MtpDatabase(getContext(), flag);
+        mProvider = new MtpDocumentsProvider();
+        mProvider.onCreateForTesting(mResources, mMtpManager, mResolver, mDatabase);
+    }
+
+    private String[] getStrings(Cursor cursor) {
+        try {
+            final String[] results = new String[cursor.getCount()];
+            for (int i = 0; cursor.moveToNext(); i++) {
+                results[i] = cursor.getString(0);
+            }
+            return results;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private String[] setupRoots(int deviceId, MtpRoot[] roots)
+            throws FileNotFoundException, InterruptedException, TimeoutException {
+        final int changeCount = mResolver.getChangeCount(ROOTS_URI);
+        mMtpManager.setRoots(deviceId, roots);
+        mResolver.waitForNotification(ROOTS_URI, changeCount + 1);
+        return getStrings(mProvider.queryRoots(strings(DocumentsContract.Root.COLUMN_ROOT_ID)));
+    }
+
+    private String[] setupDocuments(
+            int deviceId,
+            int storageId,
+            int parentHandle,
+            String parentDocumentId,
+            MtpObjectInfo[] objects) throws FileNotFoundException {
+        final int[] handles = new int[objects.length];
+        int i = 0;
+        for (final MtpObjectInfo info : objects) {
+            handles[i] = info.getObjectHandle();
+            mMtpManager.setObjectInfo(deviceId, info);
+        }
+        mMtpManager.setObjectHandles(deviceId, storageId, parentHandle, handles);
+        return getStrings(mProvider.queryChildDocuments(
+                parentDocumentId, strings(DocumentsContract.Document.COLUMN_DOCUMENT_ID), null));
     }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
index 7c947f5..ccdea03 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -44,13 +44,13 @@
     public void testReadDocument_basic() throws Exception {
         mtpManager.setImportFileBytes(0, 1, HELLO_BYTES);
         final ParcelFileDescriptor descriptor = mPipeManager.readDocument(
-                mtpManager, new Identifier(0, 0, 1));
+                mtpManager, new Identifier(0, 0, 1, null));
         assertDescriptor(descriptor, HELLO_BYTES);
     }
 
     public void testReadDocument_error() throws Exception {
         final ParcelFileDescriptor descriptor =
-                mPipeManager.readDocument(mtpManager, new Identifier(0, 0, 1));
+                mPipeManager.readDocument(mtpManager, new Identifier(0, 0, 1, null));
         assertDescriptorError(descriptor);
     }
 
@@ -62,7 +62,7 @@
 
         // Upload testing bytes.
         final ParcelFileDescriptor descriptor = mPipeManager.writeDocument(
-                getContext(), mtpManager, new Identifier(0, 0, 1));
+                getContext(), mtpManager, new Identifier(0, 0, 1, null));
         final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
                 new ParcelFileDescriptor.AutoCloseOutputStream(descriptor);
         outputStream.write(HELLO_BYTES, 0, HELLO_BYTES.length);
@@ -94,13 +94,13 @@
     public void testReadThumbnail_basic() throws Exception {
         mtpManager.setThumbnail(0, 1, HELLO_BYTES);
         final ParcelFileDescriptor descriptor = mPipeManager.readThumbnail(
-                mtpManager, new Identifier(0, 0, 1));
+                mtpManager, new Identifier(0, 0, 1, null));
         assertDescriptor(descriptor, HELLO_BYTES);
     }
 
     public void testReadThumbnail_error() throws Exception {
         final ParcelFileDescriptor descriptor =
-                mPipeManager.readThumbnail(mtpManager, new Identifier(0, 0, 1));
+                mPipeManager.readThumbnail(mtpManager, new Identifier(0, 0, 1, null));
         assertDescriptorError(descriptor);
     }
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 67e170f..6521565 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -556,8 +556,7 @@
 
         // Make sure the IME is not on the way of preview as
         // the user may have used it to type copies or range.
-        InputMethodManager imm = (InputMethodManager) getSystemService(
-                Context.INPUT_METHOD_SERVICE);
+        InputMethodManager imm = getSystemService(InputMethodManager.class);
         imm.hideSoftInputFromWindow(mDestinationSpinner.getWindowToken(), 0);
     }
 
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 8fa5abf..98a171e 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -72,7 +72,7 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Sparuj"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SPARUJ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Anuluj"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Parowanie spowoduje przyznanie dostępu do historii połączeń i Twoich kontaktów w trakcie połączenia."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Sparowanie powoduje przyznanie dostępu do historii połączeń i Twoich kontaktów w trakcie połączenia."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Nie można sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nie można sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ze względu na błędny kod PIN lub klucz."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nie można skomunikować się z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 029962e..c3c287c 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -38,7 +38,7 @@
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"กำลังตัดการเชื่อมต่อ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"กำลังเชื่อมต่อ…"</string>
     <string name="bluetooth_connected" msgid="6038755206916626419">"เชื่อมต่อแล้ว"</string>
-    <string name="bluetooth_pairing" msgid="1426882272690346242">"กำลังกำหนดค่าอุปกรณ์ให้ตรงกัน..."</string>
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"กำลังจับคู่อุปกรณ์..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"เชื่อมต่อแล้ว (ยกเว้นเสียงโทรศัพท์)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"เชื่อมต่อแล้ว (ยกเว้นเสียงสื่อ)"</string>
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"เชื่อมต่อแล้ว (ไม่มีการเข้าถึงข้อความ)"</string>
@@ -69,14 +69,14 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ใช้สำหรับระบบเสียงของโทรศัพท์"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ใช้สำหรับการโอนไฟล์"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ใช้สำหรับการป้อนข้อมูล"</string>
-    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"กำหนดค่าอุปกรณ์ให้ตรงกัน"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"จับคู่อุปกรณ์"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"จับคู่อุปกรณ์"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ยกเลิก"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"การจับคู่อุปกรณ์จะให้สิทธิ์การเข้าถึงที่อยู่ติดต่อและประวัติการโทรเมื่อเชื่อมต่อแล้ว"</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"ไม่สามารถจับคู่กับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ไม่สามารถจับคู่กับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ได้เพราะ PIN หรือรหัสผ่านไม่ถูกต้อง"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"ไม่สามารถเชื่อมต่อกับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"การกำหนดค่าอุปกรณ์ให้ตรงกันถูกปฏิเสธโดย <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ปฏิเสธการจับคู่อุปกรณ์"</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi ปิดอยู่"</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"ไม่ได้เชื่อมต่อ Wi-Fi"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"สัญญาณ Wi-Fi 1 ขีด"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index 6102bef..00dadb8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -143,6 +143,9 @@
 
     public boolean openTile(DashboardTile tile) {
         closeDrawer();
+        if (tile == null) {
+            return false;
+        }
         int numUserHandles = tile.userHandle.size();
         if (numUserHandles > 1) {
             ProfileSelectDialog.show(getFragmentManager(), tile);
diff --git a/packages/SettingsProvider/res/values-it/strings.xml b/packages/SettingsProvider/res/values-it/strings.xml
index 40735cc..ba1431d 100644
--- a/packages/SettingsProvider/res/values-it/strings.xml
+++ b/packages/SettingsProvider/res/values-it/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4567566098528588863">"Archiviazione impostazioni"</string>
+    <string name="app_label" msgid="4567566098528588863">"Memoria impostazioni"</string>
 </resources>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index bf3982d..25346ac 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -144,6 +144,7 @@
             android:name=".BugreportReceiver"
             android:permission="android.permission.DUMP">
             <intent-filter>
+                <action android:name="android.intent.action.BUGREPORT_STARTED" />
                 <action android:name="android.intent.action.BUGREPORT_FINISHED" />
             </intent-filter>
         </receiver>
diff --git a/packages/Shell/res/values/strings.xml b/packages/Shell/res/values/strings.xml
index 4469d38..cff36f7 100644
--- a/packages/Shell/res/values/strings.xml
+++ b/packages/Shell/res/values/strings.xml
@@ -17,6 +17,8 @@
 <resources>
     <string name="app_label">Shell</string>
 
+    <!-- Title of notification indicating a bugreport process is in progress. [CHAR LIMIT=50] -->
+    <string name="bugreport_in_progress_title">Bug report in progress</string>
     <!-- Title of notification indicating a bugreport has been successfully captured. [CHAR LIMIT=50] -->
     <string name="bugreport_finished_title">Bug report captured</string>
 
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index a2030ef..d0e91d2 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -21,11 +21,16 @@
 
 import java.io.BufferedOutputStream;
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.PrintWriter;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
@@ -45,26 +50,102 @@
 import android.content.res.Configuration;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcelable;
+import android.os.Process;
 import android.os.SystemProperties;
 import android.support.v4.content.FileProvider;
+import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Patterns;
+import android.util.SparseArray;
 import android.widget.Toast;
 
+/**
+ * Service used to keep progress of bug reports processes ({@code dumpstate}).
+ * <p>
+ * The workflow is:
+ * <ol>
+ * <li>When {@code dumpstate} starts, it sends a {@code BUGREPORT_STARTED} with its pid and the
+ * estimated total effort.
+ * <li>{@link BugreportReceiver} receives the intent and delegates it to this service.
+ * <li>Upon start, this service:
+ * <ol>
+ * <li>Issues a system notification so user can watch the progresss (which is 0% initially).
+ * <li>Polls the {@link SystemProperties} for updates on the {@code dumpstate} progress.
+ * <li>If the progress changed, it updates the system notification.
+ * </ol>
+ * <li>As {@code dumpstate} progresses, it updates the system property.
+ * <li>When {@code dumpstate} finishes, it sends a {@code BUGREPORT_FINISHED} intent.
+ * <li>{@link BugreportReceiver} receives the intent and delegates it to this service, which in
+ * turn:
+ * <ol>
+ * <li>Updates the system notification so user can share the bug report.
+ * <li>Stops monitoring that {@code dumpstate} process.
+ * <li>Stops itself if it doesn't have any process left to monitor.
+ * </ol>
+ * </ol>
+ */
 public class BugreportProgressService extends Service {
     private static final String TAG = "Shell";
+    private static final boolean DEBUG = false;
 
     private static final String AUTHORITY = "com.android.shell";
 
+    static final String INTENT_BUGREPORT_STARTED = "android.intent.action.BUGREPORT_STARTED";
+    static final String INTENT_BUGREPORT_FINISHED = "android.intent.action.BUGREPORT_FINISHED";
+
     static final String EXTRA_BUGREPORT = "android.intent.extra.BUGREPORT";
     static final String EXTRA_SCREENSHOT = "android.intent.extra.SCREENSHOT";
+    static final String EXTRA_PID = "android.intent.extra.PID";
+    static final String EXTRA_MAX = "android.intent.extra.MAX";
+    static final String EXTRA_NAME = "android.intent.extra.NAME";
+    static final String EXTRA_ORIGINAL_INTENT = "android.intent.extra.ORIGINAL_INTENT";
+
+    private static final int MSG_SERVICE_COMMAND = 1;
+    private static final int MSG_POLL = 2;
+
+    /** Polling frequency, in milliseconds. */
+    private static final long POLLING_FREQUENCY = 500;
+
+    /** How long (in ms) a dumpstate process will be monitored if it didn't show progress. */
+    private static final long INACTIVITY_TIMEOUT = 3 * DateUtils.MINUTE_IN_MILLIS;
+
+    /** System property used for monitoring progress. */
+    private static final String PROGRESS_PROPERTY_TEMPLATE = "dumpstate.%d.progress";
+
+    /** Managed dumpstate processes (keyed by pid) */
+    private final SparseArray<BugreportInfo> mProcesses = new SparseArray<>();
+
+    private Looper mServiceLooper;
+    private ServiceHandler mServiceHandler;
+
+    @Override
+    public void onCreate() {
+        HandlerThread thread = new HandlerThread("BugreportProgressServiceThread",
+                Process.THREAD_PRIORITY_BACKGROUND);
+        thread.start();
+
+        mServiceLooper = thread.getLooper();
+        mServiceHandler = new ServiceHandler(mServiceLooper);
+    }
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         if (intent != null) {
-            onBugreportFinished(intent);
+            // Handle it in a separate thread.
+            Message msg = mServiceHandler.obtainMessage();
+            msg.what = MSG_SERVICE_COMMAND;
+            msg.obj = intent;
+            mServiceHandler.sendMessage(msg);
         }
+
+        // If service is killed it cannot be recreated because it would not know which
+        // dumpstate PIDs it would have to watch.
         return START_NOT_STICKY;
     }
 
@@ -73,26 +154,249 @@
         return null;
     }
 
-    private void onBugreportFinished(Intent intent) {
-        final Context context = getApplicationContext();
-        final Configuration conf = context.getResources().getConfiguration();
-        final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
-        final File screenshotFile = getFileExtra(intent, EXTRA_SCREENSHOT);
+    @Override
+    public void onDestroy() {
+        mServiceLooper.quit();
+        super.onDestroy();
+    }
 
-        if ((conf.uiMode & Configuration.UI_MODE_TYPE_MASK) != Configuration.UI_MODE_TYPE_WATCH) {
-            triggerLocalNotification(context, bugreportFile, screenshotFile);
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        writer.printf("Monitored dumpstate processes: \n");
+        synchronized (mProcesses) {
+            for (int i = 0; i < mProcesses.size(); i++) {
+              writer.printf("\t%s\n", mProcesses.valueAt(i));
+            }
         }
-        stopSelf();
+    }
+
+    private final class ServiceHandler extends Handler {
+        public ServiceHandler(Looper looper) {
+            super(looper);
+            pollProgress();
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_POLL) {
+                pollProgress();
+                return;
+            }
+
+            if (msg.what != MSG_SERVICE_COMMAND) {
+                // Sanity check.
+                Log.e(TAG, "Invalid message type: " + msg.what);
+                return;
+            }
+
+            // At this point it's handling onStartCommand(), whose intent contains the extras
+            // originally received by BugreportReceiver.
+            if (!(msg.obj instanceof Intent)) {
+                // Sanity check.
+                Log.e(TAG, "Internal error: invalid msg.obj: " + msg.obj);
+                return;
+            }
+            final Parcelable parcel = ((Intent) msg.obj).getParcelableExtra(EXTRA_ORIGINAL_INTENT);
+            if (!(parcel instanceof Intent)) {
+                // Sanity check.
+                Log.e(TAG, "Internal error: msg.obj is missing extra " + EXTRA_ORIGINAL_INTENT);
+                return;
+            }
+
+            final Intent intent = (Intent) parcel;
+            final String action = intent.getAction();
+            int pid = intent.getIntExtra(EXTRA_PID, 0);
+            int max = intent.getIntExtra(EXTRA_MAX, -1);
+            String name = intent.getStringExtra(EXTRA_NAME);
+
+            if (DEBUG) Log.v(TAG, "action: " + action + ", name: " + name + ", pid: " + pid
+                    + ", max: "+ max);
+            switch (action) {
+                case INTENT_BUGREPORT_STARTED:
+                    if (!startProgress(name, pid, max)) {
+                        stopSelfWhenDone();
+                        return;
+                    }
+                    break;
+                case INTENT_BUGREPORT_FINISHED:
+                    if (pid == -1) {
+                        // Shouldn't happen, unless BUGREPORT_FINISHED is received from a legacy,
+                        // out-of-sync dumpstate process.
+                        Log.w(TAG, "Missing " + EXTRA_PID + " on intent " + intent);
+                    }
+                    stopProgress(pid, intent);
+                    break;
+                default:
+                    Log.w(TAG, "Unsupported intent: " + action);
+            }
+            return;
+
+        }
+
+        /**
+         * Creates the {@link BugreportInfo} for a process and issue a system notification to
+         * indicate its progress.
+         *
+         * @return whether it succeeded or not.
+         */
+        private boolean startProgress(String name, int pid, int max) {
+            if (name == null) {
+                Log.w(TAG, "Missing " + EXTRA_NAME + " on start intent");
+                name = "N/A";
+            }
+            if (pid == -1) {
+                Log.e(TAG, "Missing " + EXTRA_PID + " on start intent");
+                return false;
+            }
+            if (max <= 0) {
+                Log.e(TAG, "Invalid value for extra " + EXTRA_MAX + ": " + max);
+                return false;
+            }
+
+            final BugreportInfo info = new BugreportInfo(pid, name, max);
+            synchronized (mProcesses) {
+                if (mProcesses.indexOfKey(pid) >= 0) {
+                    Log.w(TAG, "PID " + pid + " already watched");
+                } else {
+                    mProcesses.put(info.pid, info);
+                }
+            }
+            updateProgress(info);
+            return true;
+        }
+
+        /**
+         * Updates the system notification for a given bug report.
+         */
+        private void updateProgress(BugreportInfo info) {
+            if (info.max <= 0 || info.progress < 0 || info.name == null) {
+                Log.e(TAG, "Invalid progress values for " + info);
+                return;
+            }
+
+            final Context context = getApplicationContext();
+            final NumberFormat nf = NumberFormat.getPercentInstance();
+            nf.setMinimumFractionDigits(2);
+            nf.setMaximumFractionDigits(2);
+            final String percentText = nf.format((double) info.progress / info.max);
+
+            final String title = context.getString(R.string.bugreport_in_progress_title);
+            final Notification notification = new Notification.Builder(context)
+                    .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                    .setContentTitle(title)
+                    .setTicker(title)
+                    .setContentText(info.name)
+                    .setContentInfo(percentText)
+                    .setProgress(info.max, info.progress, false)
+                    // TODO: .setOngoing(true) once it has a CANCEL action
+                    .setLocalOnly(true)
+                    .setColor(context.getColor(
+                            com.android.internal.R.color.system_notification_accent_color))
+                    .build();
+
+            NotificationManager.from(context).notify(TAG, info.pid, notification);
+        }
+
+        /**
+         * Finalizes the progress on a given process and sends the finished intent.
+         */
+        private void stopProgress(int pid, Intent intent) {
+            synchronized (mProcesses) {
+                if (mProcesses.indexOfKey(pid) < 0) {
+                    Log.w(TAG, "PID not watched: " + pid);
+                } else {
+                    mProcesses.remove(pid);
+                }
+                stopSelfWhenDone();
+            }
+            if (DEBUG) Log.v(TAG, "stopProgress(" + pid + "): cancel notification");
+            NotificationManager.from(getApplicationContext()).cancel(TAG, pid);
+            if (intent != null) {
+                // Bug report finished fine: send a new, different notification.
+                if (DEBUG) Log.v(TAG, "stopProgress(" + pid + "): finish bug report");
+                onBugreportFinished(pid, intent);
+            }
+        }
+
+        /**
+         * Poll {@link SystemProperties} to get the progress on each monitored process.
+         */
+        private void pollProgress() {
+            synchronized (mProcesses) {
+                if (mProcesses.size() == 0) {
+                    Log.d(TAG, "No process to poll progress.");
+                }
+                for (int i = 0; i < mProcesses.size(); i++) {
+                    int pid = mProcesses.keyAt(i);
+                    String property = String.format(PROGRESS_PROPERTY_TEMPLATE, pid);
+                    int progress;
+                    try {
+                        progress = SystemProperties.getInt(property, 0);
+                    } catch (IllegalArgumentException e) {
+                        Log.v(TAG, "Could not read system property " + property, e);
+                        continue;
+                    }
+                    if (progress == 0) {
+                        Log.v(TAG, "System property " + property + " is not set yet");
+                        continue;
+                    }
+
+                    BugreportInfo info = mProcesses.valueAt(i);
+
+                    if (progress != info.progress) {
+                        if (DEBUG) Log.v(TAG, "Updating progress for PID " + pid + " from "
+                                + info.progress + " to " + progress);
+                        info.progress = progress;
+                        info.lastUpdate = System.currentTimeMillis();
+                        updateProgress(info);
+                    } else {
+                        long inactiveTime = System.currentTimeMillis() - info.lastUpdate;
+                        if (inactiveTime >= INACTIVITY_TIMEOUT) {
+                            Log.w(TAG, "No progress update for process " + pid + " since "
+                                    + info.getFormattedLastUpdate());
+                            stopProgress(info.pid, null);
+                        }
+                    }
+                }
+                // Keep polling...
+                sendEmptyMessageDelayed(MSG_POLL, POLLING_FREQUENCY);
+            }
+        }
+
+        /**
+         * Finishes the service when it's not monitoring any more processes.
+         */
+        private void stopSelfWhenDone() {
+            synchronized (mProcesses) {
+                if (mProcesses.size() > 0) {
+                    if (DEBUG) Log.v(TAG, "Staying alive, waiting for pids " + mProcesses);
+                    return;
+                }
+                Log.v(TAG, "No more pids to handle, shutting down");
+                stopSelf();
+            }
+        }
+
+        private void onBugreportFinished(int pid, Intent intent) {
+            final Context context = getApplicationContext();
+            final Configuration conf = context.getResources().getConfiguration();
+            final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
+            final File screenshotFile = getFileExtra(intent, EXTRA_SCREENSHOT);
+
+            if ((conf.uiMode & Configuration.UI_MODE_TYPE_MASK) != Configuration.UI_MODE_TYPE_WATCH) {
+                triggerLocalNotification(context, pid, bugreportFile, screenshotFile);
+            }
+        }
     }
 
     /**
-     * Responsible for triggering a notification that allows the user to start a
-     * "share" intent with the bug report. On watches we have other methods to allow the user to
-     * start this intent (usually by triggering it on another connected device); we don't need to
-     * display the notification in this case.
+     * Responsible for triggering a notification that allows the user to start a "share" intent with
+     * the bug report. On watches we have other methods to allow the user to start this intent
+     * (usually by triggering it on another connected device); we don't need to display the
+     * notification in this case.
      */
-    private static void triggerLocalNotification(final Context context, final File bugreportFile,
-            final File screenshotFile) {
+    private static void triggerLocalNotification(final Context context, final int pid,
+            final File bugreportFile, final File screenshotFile) {
         if (!bugreportFile.exists() || !bugreportFile.canRead()) {
             Log.e(TAG, "Could not read bugreport file " + bugreportFile);
             Toast.makeText(context, context.getString(R.string.bugreport_unreadable_text),
@@ -103,10 +407,10 @@
         boolean isPlainText = bugreportFile.getName().toLowerCase().endsWith(".txt");
         if (!isPlainText) {
             // Already zipped, send it right away.
-            sendBugreportNotification(context, bugreportFile, screenshotFile);
+            sendBugreportNotification(context, pid, bugreportFile, screenshotFile);
         } else {
             // Asynchronously zip the file first, then send it.
-            sendZippedBugreportNotification(context, bugreportFile, screenshotFile);
+            sendZippedBugreportNotification(context, pid, bugreportFile, screenshotFile);
         }
     }
 
@@ -155,7 +459,7 @@
     /**
      * Sends a bugreport notitication.
      */
-    private static void sendBugreportNotification(Context context, File bugreportFile,
+    private static void sendBugreportNotification(Context context, int pid, File bugreportFile,
             File screenshotFile) {
         // Files are kept on private storage, so turn into Uris that we can
         // grant temporary permissions for.
@@ -173,10 +477,11 @@
         }
         notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
+        final String title = context.getString(R.string.bugreport_finished_title);
         final Notification.Builder builder = new Notification.Builder(context)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                .setContentTitle(context.getString(R.string.bugreport_finished_title))
-                .setTicker(context.getString(R.string.bugreport_finished_title))
+                .setContentTitle(title)
+                .setTicker(title)
                 .setContentText(context.getString(R.string.bugreport_finished_text))
                 .setContentIntent(PendingIntent.getActivity(
                         context, 0, notifIntent, PendingIntent.FLAG_CANCEL_CURRENT))
@@ -185,19 +490,19 @@
                 .setColor(context.getColor(
                         com.android.internal.R.color.system_notification_accent_color));
 
-        NotificationManager.from(context).notify(TAG, 0, builder.build());
+        NotificationManager.from(context).notify(TAG, pid, builder.build());
     }
 
     /**
      * Sends a zipped bugreport notification.
      */
     private static void sendZippedBugreportNotification(final Context context,
-            final File bugreportFile, final File screenshotFile) {
+            final int pid, final File bugreportFile, final File screenshotFile) {
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
                 File zippedFile = zipBugreport(bugreportFile);
-                sendBugreportNotification(context, zippedFile, screenshotFile);
+                sendBugreportNotification(context, pid, zippedFile, screenshotFile);
                 return null;
             }
         }.execute();
@@ -213,8 +518,8 @@
         Log.v(TAG, "zipping " + bugreportPath + " as " + zippedPath);
         File bugreportZippedFile = new File(zippedPath);
         try (InputStream is = new FileInputStream(bugreportFile);
-            ZipOutputStream zos = new ZipOutputStream(
-                new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) {
+                ZipOutputStream zos = new ZipOutputStream(
+                        new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) {
             ZipEntry entry = new ZipEntry(bugreportFile.getName());
             entry.setTime(bugreportFile.lastModified());
             zos.putNextEntry(entry);
@@ -230,8 +535,8 @@
             }
             return bugreportZippedFile;
         } catch (IOException e) {
-          Log.e(TAG, "exception zipping file " + zippedPath, e);
-          return bugreportFile;  // Return original.
+            Log.e(TAG, "exception zipping file " + zippedPath, e);
+            return bugreportFile; // Return original.
         }
     }
 
@@ -281,4 +586,55 @@
             return null;
         }
     }
+
+    /**
+     * Information about a bug report process while its in progress.
+     */
+    private static final class BugreportInfo {
+        /**
+         * {@code pid} of the {@code dumpstate} process generating the bug report.
+         */
+        final int pid;
+
+        /**
+         * Name of the bug report, will be used to rename the final files.
+         * <p>
+         * Initial value is the bug report filename reported by {@code dumpstate}, but user can
+         * change it later to a more meaningful name.
+         */
+        final String name;
+
+        /**
+         * Maximum progress of the bug report generation.
+         */
+        final int max;
+
+        /**
+         * Current progress of the bug report generation.
+         */
+        int progress;
+
+        /**
+         * Time of the last progress update.
+         */
+        long lastUpdate = System.currentTimeMillis();
+
+        BugreportInfo(int pid, String name, int max) {
+            this.pid = pid;
+            this.name = name;
+            this.max = max;
+        }
+
+        String getFormattedLastUpdate() {
+            return SimpleDateFormat.getDateTimeInstance().format(new Date(lastUpdate));
+        }
+
+        @Override
+        public String toString() {
+            final float percent = ((float) progress * 100 / max);
+            return String.format("Progress for %s (pid=%d): %d/%d (%2.2f%%) Last update: %s", name,
+                    pid, progress, max, percent,
+                    getFormattedLastUpdate());
+        }
+    }
 }
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index f1da14d..5133162 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -17,6 +17,8 @@
 package com.android.shell;
 
 import static com.android.shell.BugreportProgressService.EXTRA_BUGREPORT;
+import static com.android.shell.BugreportProgressService.EXTRA_ORIGINAL_INTENT;
+import static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_FINISHED;
 import static com.android.shell.BugreportProgressService.getFileExtra;
 
 import java.io.File;
@@ -50,13 +52,16 @@
         // Clean up older bugreports in background
         cleanupOldFiles(intent);
 
-        // Delegate to service.
+        // Delegate intent handling to service.
         Intent serviceIntent = new Intent(context, BugreportProgressService.class);
-        serviceIntent.putExtras(intent.getExtras());
+        serviceIntent.putExtra(EXTRA_ORIGINAL_INTENT, intent);
         context.startService(serviceIntent);
     }
 
     private void cleanupOldFiles(Intent intent) {
+        if (!INTENT_BUGREPORT_FINISHED.equals(intent.getAction())) {
+            return;
+        }
         final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
         final PendingResult result = goAsync();
         new AsyncTask<Void, Void, Void>() {
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index 1bdd9dd..33c4ef1 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -19,7 +19,12 @@
 import static android.test.MoreAsserts.assertContainsRegex;
 import static com.android.shell.ActionSendMultipleConsumerActivity.UI_NAME;
 import static com.android.shell.BugreportProgressService.EXTRA_BUGREPORT;
+import static com.android.shell.BugreportProgressService.EXTRA_MAX;
+import static com.android.shell.BugreportProgressService.EXTRA_NAME;
+import static com.android.shell.BugreportProgressService.EXTRA_PID;
 import static com.android.shell.BugreportProgressService.EXTRA_SCREENSHOT;
+import static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_FINISHED;
+import static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_STARTED;
 
 import java.io.BufferedOutputStream;
 import java.io.BufferedWriter;
@@ -96,6 +101,33 @@
         cancelExistingNotifications();
     }
 
+    public void testFullWorkflow() throws Exception {
+        final String name = "BUG, Y U NO REPORT?";
+        // TODO: call method to remove property instead
+        SystemProperties.set("dumpstate.42.progress", "-1");
+
+        Intent intent = new Intent(INTENT_BUGREPORT_STARTED);
+        intent.putExtra(EXTRA_PID, 42);
+        intent.putExtra(EXTRA_NAME, name);
+        intent.putExtra(EXTRA_MAX, 1000);
+        mContext.sendBroadcast(intent);
+
+        assertProgressNotification(name, "0.00%");
+
+        SystemProperties.set("dumpstate.42.progress", "108");
+        assertProgressNotification(name, "10.80%");
+
+        SystemProperties.set("dumpstate.42.progress", "500");
+        assertProgressNotification(name, "50.00%");
+
+        createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT);
+        createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT);
+        Bundle extras = sendBugreportFinishedIntent(42, PLAIN_TEXT_PATH, SCREENSHOT_PATH);
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
+
+        // TODO: assert service is down
+    }
+
     public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception {
         createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT);
         createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT);
@@ -131,13 +163,32 @@
         }
     }
 
+    private void assertProgressNotification(String name, String percent) {
+        // TODO: it current looks for 3 distinct objects, without taking advantage of their
+        // relationship.
+        String title = mContext.getString(R.string.bugreport_in_progress_title);
+        Log.v(TAG, "Looking for progress notification title: '" + title+ "'");
+        mUiBot.getNotification(title);
+        Log.v(TAG, "Looking for progress notification details: '" + name + "-" + percent + "'");
+        mUiBot.getObject(name);
+        mUiBot.getObject(percent);
+    }
+
     /**
      * Sends a "bugreport finished" intent and waits for the result.
      *
      * @return extras sent to the bugreport finished consumer.
      */
     private Bundle sendBugreportFinishedIntent(String bugreportPath, String screenshotPath) {
-        Intent intent = new Intent("android.intent.action.BUGREPORT_FINISHED");
+        return sendBugreportFinishedIntent(null, bugreportPath, screenshotPath);
+    }
+
+    private Bundle sendBugreportFinishedIntent(Integer pid, String bugreportPath,
+            String screenshotPath) {
+        Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
+        if (pid != null) {
+            intent.putExtra(EXTRA_PID, pid);
+        }
         if (bugreportPath != null) {
             intent.putExtra(EXTRA_BUGREPORT, bugreportPath);
         }
diff --git a/packages/Shell/tests/src/com/android/shell/UiBot.java b/packages/Shell/tests/src/com/android/shell/UiBot.java
index f5dd31c..fa1714e 100644
--- a/packages/Shell/tests/src/com/android/shell/UiBot.java
+++ b/packages/Shell/tests/src/com/android/shell/UiBot.java
@@ -42,32 +42,49 @@
     }
 
     /**
-     * Opens the system notification and clicks a given notification.
+     * Opens the system notification and gets a given notification.
      *
      * @param text Notificaton's text as displayed by the UI.
+     * @return notification object.
      */
-    public void clickOnNotification(String text) {
+    public UiObject getNotification(String text) {
         boolean opened = mDevice.openNotification();
         Log.v(TAG, "openNotification(): " + opened);
         boolean gotIt = mDevice.wait(Until.hasObject(By.pkg(SYSTEMUI_PACKAGED)), mTimeout);
         assertTrue("could not get system ui (" + SYSTEMUI_PACKAGED + ")", gotIt);
 
-        gotIt = mDevice.wait(Until.hasObject(By.text(text)), mTimeout);
-        assertTrue("object with text '(" + text + "') not visible yet", gotIt);
+        return getObject(text);
+    }
 
-        UiObject notification = getVisibleObject(text);
-
+    /**
+     * Opens the system notification and clicks a given notification.
+     *
+     * @param text Notificaton's text as displayed by the UI.
+     */
+    public void clickOnNotification(String text) {
+        UiObject notification = getNotification(text);
         click(notification, "bug report notification");
     }
 
     /**
-     * Gets an object which is guaranteed to be present in the current UI.\
+     * Gets an object that might not yet be available in current UI.
+     *
+     * @param text Object's text as displayed by the UI.
+     */
+    public UiObject getObject(String text) {
+        boolean gotIt = mDevice.wait(Until.hasObject(By.text(text)), mTimeout);
+        assertTrue("object with text '(" + text + "') not visible yet", gotIt);
+        return getVisibleObject(text);
+    }
+
+    /**
+     * Gets an object which is guaranteed to be present in the current UI.
      *
      * @param text Object's text as displayed by the UI.
      */
     public UiObject getVisibleObject(String text) {
         UiObject uiObject = mDevice.findObject(new UiSelector().text(text));
-        assertTrue("could not find object with text '(" + text + "')", uiObject.exists());
+        assertTrue("could not find object with text '" + text + "'", uiObject.exists());
         return uiObject;
     }
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 1e18523..7006d43 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skermvaspen"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kon nie <xliff:g id="APP">%s</xliff:g> begin nie."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Meer"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Geskiedenis"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Verdeel horisontaal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Verdeel vertikaal"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Verdeel gepasmaak"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Wys horlosiesekondes op die statusbalk. Sal batterylewe dalk beïnvloed."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Herrangskik Kitsinstellings"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Wys helderheid in Kitsinstellings"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Aktiveer oproep"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Aktiveer oproep deur die Oorsig-knoppie"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Aktiveer vinnige wissel"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Aktiveer beginuitteltyd terwyl daar opgeroep word"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Aktiveer volskerm-skermkiekies"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Aktiveer volskerm-skermkiekies in Oorsig"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimenteel"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Skakel Bluetooth aan?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Jy moet Bluetooth aanskakel om jou sleutelbord aan jou tablet te koppel."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 8dae911..948c538 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ማያ ገጽ መሰካት"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ን መጀመር አልተቻለም።"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"ተጨማሪ"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ታሪክ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"አግድም ክፈል"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ቁልቁል ክፈል"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"በብጁ ክፈል"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"የሰዓት ሰከንዶችን በሁኔታ አሞሌ ውስጥ አሳይ። በባትሪ ዕድሜ ላይ ተጽዕኖ ሊኖርው ይችል ይሆናል።"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ፈጣን ቅንብሮችን ዳግም ያደራጁ"</string>
     <string name="show_brightness" msgid="6613930842805942519">"በፈጣን ቅንብሮች ውስጥ ብሩህነትን አሳይ"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"ገጽ መስራትን አንቃ"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"በአጠቃላይ እይታ አዝራር በኩል ገጽ መስራትን አንቃ"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"ፈጣን ቅይይርን አንቃ"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"ገጽ እየሰራ ሳለ የማስጀመሪያ ጊዜ ማብቂያውን አንቃ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"የሙሉ ማያ ገጽ ቅጽበታዊ ገጽ እይታዎችን አንቃ"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"በአጠቃላይ እይታ ውስጥ የሙሉ ማያ ገጽ ቅጽበታዊ ገጽ እይታዎችን አንቃ"</string>
     <string name="experimental" msgid="6198182315536726162">"የሙከራ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ብሉቱዝ ይብራ?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"የቁልፍ ሰሌዳዎን ከእርስዎ ጡባዊ ጋር ለማገናኘት በመጀመሪያ ብሉቱዝን ማብራት አለብዎት።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index b7d85b7..e272364 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -298,6 +298,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"تثبيت الشاشة"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"تعذر بدء <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"المزيد"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"السجلّ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسيم أفقي"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"تقسيم رأسي"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"تقسيم مخصص"</string>
@@ -441,12 +443,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"عرض ثواني الساعة في شريط الحالة. قد يؤثر ذلك في عمر البطارية."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"إعادة ترتيب الإعدادات السريعة"</string>
     <string name="show_brightness" msgid="6613930842805942519">"عرض السطوع في الإعدادات السريعة"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"تمكين الترحيل"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"تمكين الترحيل عبر زر \"نظرة عامة\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"تمكين التبديل السريع"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"تمكين مهلة الإطلاق أثناء الترحيل"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"تمكين اللقطات بملء الشاشة"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"تمكين اللقطات بملء الشاشة في النظرة العامة"</string>
     <string name="experimental" msgid="6198182315536726162">"إعدادات تجريبية"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"تشغيل البلوتوث؟"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"لتوصيل لوحة المفاتيح بالجهاز اللوحي، يلزمك تشغيل بلوتوث أولاً."</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index b872db3..7f2a6b07 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekran sancağı"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"axtarış"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlana bilmir."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Daha çox"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Tarixçə"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Üfüqi Böl"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Şaquli Böl"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Fərdi Böl"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Saatın saniyəsini status panelində göstərin. Batareyaya təsir edə bilər."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Sürətli Ayarları yenidən tənzimləyin"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Sürətli ayarlarda parlaqlılığı göstərin"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Səhifə nömrələməni aktiv edin"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Baxış düyməsi vasitəsilə səhifələməni aktiv edin"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Sürətli keçidi aktiv edin"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Səhifə nömrələyərkən işə salma vaxtının bitməsini aktiv edin"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Tam ekran ani görüntülərini aktiv edin"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Tam ekran ani görüntülərini İcmalda aktiv edin"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth aktivləşsin?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Tabletinizlə klaviaturaya bağlanmaq üçün ilk olaraq Bluetooth\'u aktivləşdirməlisiniz."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index fd5ddbf..6ed2adb 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"фиксиране на екрана"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не можа да стартира."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Още"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"История"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хоризонтално разделяне"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Вертикално разделяне"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Персонализирано разделяне"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Показване на секундите на часовника в лентата на състоянието. Може да се отрази на живота на батерията."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Пренареждане на бързите настройки"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Показване на яркостта от бързите настройки"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Активиране на разделянето на страници"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Активиране на разделянето на страници чрез бутона за общ преглед"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Активиране на бързото превключване"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Активиране на времето за изчакване при стартиране за разделянето на страници"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Активиране на екранните снимки на цял екран"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Активиране на екранните снимки на цял екран в режима на общ преглед"</string>
     <string name="experimental" msgid="6198182315536726162">"Експериментални"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Да се включи ли Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"За да свържете клавиатурата с таблета си, първо трябва да включите Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 442b179..20e2c35 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"স্ক্রীন পিন করা"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"আরো"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ইতিহাস"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"অনুভূমিক স্প্লিট"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"উল্লম্ব স্প্লিট"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"কাস্টম স্প্লিট করুন"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"স্থিতি দন্ডে ঘড়ির সেকেন্ড দেখায়৷ ব্যাটারি লাইফকে প্রভাবিত করতে পারে৷"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"দ্রুত সেটিংসে পুনরায় সাজান"</string>
     <string name="show_brightness" msgid="6613930842805942519">"দ্রুত সেটিংসে উজ্জ্বলতা দেখান"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"পেজিং সক্ষম করুন"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"\'এক নজরে\' বোতামের মাধ্যমে পেজিং সক্ষম করুন"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"\'দ্রুত টগল করা\'র ব্যবস্থাটি সক্ষম করুন"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"পেজিং এর সময় \'লঞ্চ সময় সমাপ্ত\' সক্ষম করুন"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"পূর্ণস্ক্রীন স্ক্রীনশট সক্ষম করুন"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"\'এক নজরে\'র মধ্যে পূর্ণস্ক্রীন স্ক্রীনশট সক্ষম করুন"</string>
     <string name="experimental" msgid="6198182315536726162">"পরীক্ষামূলক"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth চালু করবেন?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"আপনার ট্যাবলেটের সাথে আপনার কীবোর্ড সংযুক্ত করতে, আপনাকে প্রথমে Bluetooth চালু করতে হবে।"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index f67b425..0bb4826 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixació de pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No s\'ha pogut iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Més"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historial"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisió horitzontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisió vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisió personalitzada"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra els segons del rellotge a la barra d\'estat. Això pot afectar la durada de la bateria."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganitza Configuració ràpida"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a Configuració ràpida"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Activa la paginació"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Activa la paginació mitjançant el botó Visió general"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Activa el canvi ràpid"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Activa el temps d\'espera de llançament durant la paginació"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Activa les captures de pantalla completa"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Activa les captures de pantalla completa a Visió general"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vols activar el Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Per connectar el teclat amb la tauleta, primer has d\'activar el Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 08d833e..63a16ad 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"připnutí obrazovky"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikaci <xliff:g id="APP">%s</xliff:g> nelze spustit."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Další"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historie"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vodorovné rozdělení"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikální rozdělení"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Vlastní rozdělení"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Na stavovém řádku se bude zobrazovat sekundová ručička. Může být ovlivněna výdrž baterie."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Změnit uspořádání Rychlého nastavení"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Zobrazit jas v Rychlém nastavení"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Povolit stránkování"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Povolit stránkování pomocí tlačítka Přehled"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Povolit rychlé přepínání"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Povolit časový limit pro spuštění při stránkování"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Povolit snímky celé obrazovky"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Povolit snímky celé obrazovky v Přehledu"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentální"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Zapnout Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Chcete-li klávesnici připojit k tabletu, nejdříve musíte zapnout Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1fb1a51..eb8053d 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"bliv i app"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mere"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historik"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Opdel vandret"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Opdel lodret"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Opdel brugerdefineret"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statuslinjen. Dette kan påvirke batteriets levetid."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Omarranger Hurtige indstillinger"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Vis lysstyrke i Hurtige indstillinger"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Aktivér sideopdeling"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Aktivér sideopdeling via knappen Oversigt"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Aktivér hurtigt skift"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Aktivér åbningstimeout ved sideinddeling"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Aktivér skærmbilleder i fuld størrelse"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Aktivér skærmbilleder i fuld størrelse i Oversigt"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentel"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vil du slå Bluetooth til?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Bluetooth skal være slået til, før du kan knytte dit tastatur til din tablet."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index a9196d6..e156c92 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Bildschirmfixierung"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mehr"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Verlauf"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Geteilte Schaltfläche – horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Geteilte Schaltfläche – vertikal"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Geteilte Schaltfläche – benutzerdefiniert"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Uhrsekunden in der Statusleiste anzeigen. Kann sich auf die Akkulaufzeit auswirken."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Schnelleinstellungen neu anordnen"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Helligkeit in den Schnelleinstellungen anzeigen"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Paging aktivieren"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Paging über die Schaltfläche \"Übersicht\" aktivieren"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Schnelles Wechseln aktivieren"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Beim Paging Zeitlimit für Start aktivieren"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Vollbild-Screenshots aktivieren"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Vollbild-Screenshots in der Übersicht aktivieren"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentell"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth aktivieren?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Zum Verbinden von Tastatur und Tablet muss Bluetooth aktiviert sein."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index e982df6..b0dcc40 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"καρφίτσωμα οθόνης"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Δεν ήταν δυνατή η εκκίνηση της εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Περισσότερα"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Ιστορικό"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Οριζόντιος διαχωρισμός"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Κάθετος διαχωρισμός"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Προσαρμοσμένος διαχωρισμός"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Εμφάνιση δευτερολέπτων ρολογιού στη γραμμή κατάστασης. Ενδέχεται να επηρεάσει τη διάρκεια ζωής της μπαταρίας."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Αναδιάταξη Γρήγορων ρυθμίσεων"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Εμφάνιση φωτεινότητας στις Γρήγορες ρυθμίσεις"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Ενεργοποίηση σελιδοποίησης"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Ενεργοποίηση σελιδοποίησης μέσω του κουμπιού \"Επισκόπηση\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Ενεργοποίηση γρήγορης εναλλαγής"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Ενεργοποίηση του χρονικού ορίου λήξης εκκίνησης κατά τη σελιδοποίηση"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Ενεργοποίηση στιγμιοτύπων πλήρους οθόνης"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Ενεργοποίηση των στιγμιοτύπων πλήρους οθόνης στην Προεπισκόπηση"</string>
     <string name="experimental" msgid="6198182315536726162">"Σε πειραματικό στάδιο"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Ενεργοποίηση Bluetooth;"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Για να συνδέσετε το πληκτρολόγιο με το tablet σας, θα πρέπει πρώτα να ενεργοποιήσετε το Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 32c486f..84f1785 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"More"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"History"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Enable paging"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Enable paging via the Overview button"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Enable fast toggle"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Enable launch timeout while paging"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Enable fullscreen screenshots"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Enable fullscreen screenshots in Overview"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 32c486f..84f1785 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"More"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"History"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Enable paging"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Enable paging via the Overview button"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Enable fast toggle"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Enable launch timeout while paging"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Enable fullscreen screenshots"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Enable fullscreen screenshots in Overview"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 32c486f..84f1785 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"More"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"History"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Enable paging"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Enable paging via the Overview button"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Enable fast toggle"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Enable launch timeout while paging"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Enable fullscreen screenshots"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Enable fullscreen screenshots in Overview"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 27451ec6..c9af193 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Fijar pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No se pudo iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Más"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historial"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"División vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"División personalizada"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar la duración de la batería."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar la Configuración rápida"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar el brillo en la Configuración rápida"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Habilitar paginación"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Habilita la paginación a través del botón Recientes"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Habilitar la activación rápida"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Habilita el tiempo de espera de inicio durante la paginación"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Habilitar capturas de pantalla en pantalla completa"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Habilita las capturas de pantalla en pantalla completa en Recientes"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"¿Activar Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar el teclado con la tablet, primero debes activar Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 1a7fea5..51984bf 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fijación de pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No se ha podido iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Más"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historial"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"División vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"División personalizada"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar a la duración de la batería."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar Ajustes rápidos"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar brillo en Ajustes rápidos"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Habilitar paginación"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Habilitar paginación con el botón Visión general"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Habilitar activación rápida"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Habilitar tiempo de espera de lanzamiento durante paginación"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Habilitar capturas de pantalla completa"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Habilitar capturas de pantalla completa en Visión general"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"¿Activar Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para poder conectar tu teclado a tu tablet, debes activar el Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 1369252..b527b9f 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekraanikuva kinnitamine"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Rohkem"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Ajalugu"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horisontaalne poolitamine"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikaalne poolitamine"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Kohandatud poolitamine"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Olekuribal kella sekundite kuvamine. See võib mõjutada aku kasutusaega."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Korralda kiirseaded ümber"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Kuva kiirseadetes heledus"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Luba sirvimine"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Saate lubada sirvimise nupuga Ülevaade"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Luba kiire vahetamine"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Luba sirvimisel käivitamise ajalõpp"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Luba täisekraanil ekraanipildid"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Saate lubada lehel Ülevaade täisekraanil ekraanipildid"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentaalne"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Kas lülitada Bluetooth sisse?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Klaviatuuri ühendamiseks tahvelarvutiga peate esmalt Bluetoothi sisse lülitama."</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 6a5212e..b7cfb2a2 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pantaila-ainguratzea"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"bilatu"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ezin izan da hasi <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Gehiago"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historia"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Banaketa horizontala"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Banaketa bertikala"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Banaketa pertsonalizatua"</string>
@@ -437,12 +439,6 @@
     <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 distira Ezarpen bizkorretan"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Gaitu orriak pasatzeko aukera"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Gaitu ikuspegi orokorraren botoiaren bidez orriak pasatzeko aukera"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Gaitu bizkor aldatzeko aukera"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Gaitu orriak pasatu bitarteko abiarazteen denbora-muga"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Gaitu pantaila osoko pantaila-argazkiak"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Gaitu pantaila osoko pantaila-argazkiak ikuspegi orokorrean"</string>
     <string name="experimental" msgid="6198182315536726162">"Esperimentala"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth eginbidea aktibatu nahi duzu?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Teklatua tabletara konektatzeko, Bluetooth eginbidea aktibatu behar duzu."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 6bfef66..b3d8216 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"پین کردن صفحه"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> شروع نشد."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"بیشتر"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"سابقه"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسیم افقی"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"تقسیم عمودی"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"سفارشی کردن تقسیم"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"ثانیه‌های ساعت را در نوار وضعیت نشان می‌دهد. ممکن است بر ماندگاری باتری تأثیر بگذارد."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ترتیب مجدد در تنظیمات سریع"</string>
     <string name="show_brightness" msgid="6613930842805942519">"نمایش روشنایی در تنظیمات سریع"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"فعال کردن صفحه‌بندی"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"فعال کردن صفحه‌بندی از طریق دکمه «نمای کلی»"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"فعال کردن جابه‌جایی سریع"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"فعال کردن مهلت زمانی راه‌اندازی هنگام صفحه‌بندی"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"فعال کردن عکس‌های صفحه‌نمایش تمام‌صفحه"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"فعال کردن عکس‌های صفحه‌نمایش تمام‌صفحه در مرور کلی"</string>
     <string name="experimental" msgid="6198182315536726162">"آزمایشی"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"بلوتوث روشن شود؟"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"برای مرتبط کردن صفحه‌کلید با رایانه لوحی، ابتدا باید بلوتوث را روشن کنید."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 4d0debe..235eef0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"näytön kiinnitys"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Sovelluksen <xliff:g id="APP">%s</xliff:g> käynnistäminen epäonnistui."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Lisää"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historia"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vaakasuuntainen jako"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Pystysuuntainen jako"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Muokattu jako"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Näytä sekunnit tilapalkin kellossa. Tämä voi vaikuttaa akun kestoon."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Järjestä pika-asetukset uudelleen"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Näytä kirkkaus pika-asetuksissa"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Ota sivutus käyttöön"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Ottaa sivutuksen käyttöön Yleiskatsaus-painikkeen avulla."</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Ota käyttöön nopea päälle/pois-toiminto."</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Ottaa käynnistyksen aikakatkaisun käyttöön sivutuksen aikana."</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Salli koko ruudun kuvakaappaukset"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Sallii koko ruudun kuvakaappaukset Viimeisimmät-näkymässä."</string>
     <string name="experimental" msgid="6198182315536726162">"Kokeellinen"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Otetaanko Bluetooth käyttöön?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Jotta voit yhdistää näppäimistön tablettiisi, sinun on ensin otettava Bluetooth käyttöön."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 24a033f..3493067 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Plus"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historique"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Séparation verticale"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Séparation personnalisée"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Afficher les secondes sur l\'horloge dans la barre d\'état. Cela peut réduire l\'autonomie de la pile."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Réorganiser les paramètres rapides"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Afficher la luminosité dans les paramètres rapides"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Activer la mise en page"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Activer la mise en page à l\'aide du bouton Aperçu"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Activer le basculement rapide"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Activer le délai avant expiration du lancement pendant la mise en page"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Activer les saisies d\'écran plein écran"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Activer les saisies d\'écran plein écran dans Aperçu"</string>
     <string name="experimental" msgid="6198182315536726162">"Fonctions expérimentales"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Activer Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Pour connecter votre clavier à votre tablette, vous devez d\'abord activer la connectivité Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d652251..ebed6e9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Plus"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historique"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Séparation verticale"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Séparation personnalisée"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Afficher les secondes dans la barre d\'état. Cela risque de réduire l\'autonomie de la batterie."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Réorganiser la fenêtre de configuration rapide"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Afficher la luminosité dans fenêtre de configuration rapide"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Activer la mise en page"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Activer la mise en page via le bouton Aperçu"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Activer le basculement rapide"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Activer le délai avant expiration du lancement pendant la mise en page"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Activer les captures d\'écran en plein écran"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Activer les captures d\'écran en plein écran en mode Aperçu"</string>
     <string name="experimental" msgid="6198182315536726162">"Paramètres expérimentaux"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Activer le Bluetooth ?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Pour connecter un clavier à votre tablette, vous devez avoir activé le Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 3a8b986..a9648b9 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixación de pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Non foi posible iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Máis"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historial"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dividir en horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Dividir en vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Dividir de xeito personalizado"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra os segundos do reloxo na barra de estado. Pode influír na duración da batería."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar Configuración rápida"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar brillo en Configuración rápida"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Activar paxinación"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Activar paxinación a través do botón Visión xeral"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Activar alternancia rápida"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Activa o tempo de espera do lanzamento durante a paxinación"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Activa as capturas de pantalla en pantalla completa"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Activa as capturas de pantalla en pantalla completa en Visión xeral"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Queres activar o Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar o teu teclado co tablet, primeiro tes que activar o Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 86c1502..804a940 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"સ્ક્રીન પિનિંગ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"શોધ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી શકાયું નથી."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"વધુ"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ઇતિહાસ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"આડું વિભક્ત કરો"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ઊભું વિભક્ત કરો"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"કસ્ટમ વિભક્ત કરો"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"ઘડિયાળ સેકન્ડ સ્થિતિ બારમાં બતાવો. બૅટરીની આવરદા પર અસર કરી શકે છે."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ઝડપી સેટિંગ્સને ફરીથી ગોઠવો"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ઝડપી સેટિંગ્સમાં તેજ બતાવો"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"પેજિંગ સક્ષમ કરો"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"વિહંગાવલોકન બટન મારફતે પેજિંગ સક્ષમ કરો"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"ઝડપી ટૉગલ સક્ષમ કરો"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"પેજિંગ વખતે લોંચ સમયસમાપ્તિ સક્ષમ કરો"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"પૂર્ણસ્ક્રીન સ્ક્રીનશોટ્સ સક્ષમ કરો"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"વિહંગાવલોકનમાં પૂર્ણસ્ક્રીન સ્ક્રીનશોટ્સ સક્ષમ કરો"</string>
     <string name="experimental" msgid="6198182315536726162">"પ્રાયોગિક"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ચાલુ કરવુ છે?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"તમારા ટેબ્લેટ સાથે કીબોર્ડ કનેક્ટ કરવા માટે, તમારે પહેલાં Bluetooth ચાલુ કરવાની જરૂર પડશે."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 834d025..354de04 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रीन पिन करना"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"अधिक"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"इतिहास"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज रूप से विभाजित करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"लम्बवत रूप से विभाजित करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"कस्‍टम रूप से विभाजित करें"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"स्थिति बार में घड़ी के सेकंड दिखाएं. इससे बैटरी के जीवनकाल पर प्रभाव पड़ सकता है."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"त्वरित सेटिंग को पुन: व्यवस्थित करें"</string>
     <string name="show_brightness" msgid="6613930842805942519">"त्वरित सेटिंग में स्क्रीन की रोशनी दिखाएं"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"पेजिंग सक्षम करें"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"अवलोकन बटन के माध्‍यम से पेजिंग सक्षम करें"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"तेज़ टॉगल सक्षम करें"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"पेजिंग के दौरान लॉन्‍च समयबाह्य सक्षम करें"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"पूर्णस्‍क्रीन स्‍क्रीनशॉट सक्षम करें"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"अवलोकन में पूर्ण स्‍क्रीनशॉट सक्षम करें"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रयोगात्मक"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटूथ चालू करें?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"अपने कीबोर्ड को अपने टैबलेट से कनेक्ट करने के लिए, आपको पहले ब्लूटूथ चालू करना होगा."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index c929d9c..b35360e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -295,6 +295,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"prikvačivanje zaslona"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Više"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Povijest"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podijeli vodoravno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podijeli okomito"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Podijeli prilagođeno"</string>
@@ -438,12 +440,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikazuju se sekunde na satu na traci statusa. Može utjecati na trajanje baterije."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Promijeni raspored Brzih postavki"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Prikaži svjetlinu u Brzim postavkama"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Omogući pregledavanje stranica"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Omogućivanje pregledavanja stranica gumbom Pregled"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Omogući brzo prebacivanje"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Omogućivanje vremenskog ograničenja pokretanja tijekom pregledavanja stranica"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Omogući snimanje cijelog zaslona"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Omogući snimanje cijelog zaslona u Pregledu"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentalno"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Želite li uključiti Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Da biste povezali tipkovnicu s tabletom, morate uključiti Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 145d904..7956a21 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"képernyő rögzítése"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nem lehet elindítani a következőt: <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Továbbiak"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Előzmények"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Osztott vízszintes"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Osztott függőleges"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Osztott egyéni"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Másodpercek megjelenítése az állapotsor óráján. Ez hatással lehet az akkumulátor üzemidejére."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Gyorsbeállítások átrendezése"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Fényerő megjelenítése a gyorsbeállításokban"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Lapozás engedélyezése"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Lapozás engedélyezése az Áttekintés gombbal"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Gyors váltás engedélyezése"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Indítási időtúllépés engedélyezése lapozás közben"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Teljes képernyős képernyőképek engedélyezése"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Teljes képernyős képernyőképek engedélyezése Áttekintés módban"</string>
     <string name="experimental" msgid="6198182315536726162">"Kísérleti"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Engedélyezi a Bluetooth-kapcsolatot?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ha a billentyűzetet csatlakoztatni szeretné táblagépéhez, először engedélyeznie kell a Bluetooth-kapcsolatot."</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 5a6ec62..de70fec 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"էկրանի ամրակցում"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Հնարավոր չէ գործարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Ավելին"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Պատմություն"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Հորիզոնական տրոհում"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Ուղղահայաց տրոհում"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Հատուկ տրոհում"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Ցույց տալ ժամացույցի վայրկյանները կարգավիճակի տողում: Կարող է ազդել մարտկոցի աշխատանքի ժամանակի վրա:"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Վերադասավորել Արագ կարգավորումները"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Ցույց տալ պայծառությունն Արագ կարգավորումներում"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Միացնել թերթումը"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Միացնել Համատեսք կոճակի միջոցով թերթումը"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Միացնել արագ փոխարկումը"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Միացնել գործարկման ժամանակի սպառումը թերթելու ժամանակ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Միացնել էկրանի պատկերների լիաէկրան ցուցադրումը"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Միացնել էկրանի պատկերների լիաէկրան ցուցադրումը Համատեսքում"</string>
     <string name="experimental" msgid="6198182315536726162">"Փորձնական"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Միացնե՞լ Bluetooth-ը:"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ստեղնաշարը ձեր պլանշետին միացնելու համար նախ անհրաժեշտ է միացնել Bluetooth-ը:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index cb2fe53..51ddcc0 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pin ke layar"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulai <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Lainnya"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Riwayat"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Pisahkan Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Pisahkan Vertikal"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Pisahkan Khusus"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Tampilkan detik jam di bilah status. Dapat memengaruhi masa pakai baterai."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Atur Ulang Setelan Cepat"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Tampilkan kecerahan di Setelan Cepat"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Aktifkan tampilan laman"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Mengaktifkan tampilan laman melalui tombol Ringkasan"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Mengaktifkan pengalih cepat"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Aktifkan waktu tunggu peluncuran saat menampilkan laman"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Aktifkan tangkapan layar untuk layar penuh"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Aktifkan tangkapan layar untuk layar penuh di Ringkasan"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Aktifkan Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Untuk menghubungkan keyboard dengan tablet, terlebih dahulu aktifkan Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 63a4fe8..20d8693 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skjáfesting"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"leita"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ekki var hægt að ræsa <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Meira"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Ferill"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Lárétt skipting"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Lóðrétt skipting"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Sérsniðin skipting"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Sýna sekúndur á klukku í stöðustikunni. Getur haft áhrif á endingu rafhlöðu."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Endurraða flýtistillingum"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Sýna birtustig í flýtistillingum"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Kveikja á síðuskoðun"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Virkja síðuskoðun með yfirlitshnappinum"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Kveikja á flýtiskiptingum"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Kveikja á tímamörkum ræsingar þegar flett er"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Kveikja á skjámyndum sem fylla upp í skjáinn"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Kveikja á skjámyndum sem fylla upp í skjáinn í yfirliti"</string>
     <string name="experimental" msgid="6198182315536726162">"Tilraunastillingar"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Kveikja á Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Til að geta tengt lyklaborðið við spjaldtölvuna þarftu fyrst að kveikja á Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 24bb49f3..87267995 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"blocco su schermo"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossibile avviare <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Altro"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Cronologia"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisione in orizzontale"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisione in verticale"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisione personalizzata"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra i secondi nell\'orologio nella barra di stato. Ciò potrebbe ridurre la durata della carica della batteria."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Riorganizza Impostazioni rapide"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostra luminosità in Impostazioni rapide"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Attiva paging"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Attiva il paging tramite il pulsante Panoramica"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Abilita attivazione/disattivazione veloce"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Attiva timeout lancio durante il paging"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Attiva screenshot a schermo intero"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Attiva screenshot a schermo intero in Panoramica"</string>
     <string name="experimental" msgid="6198182315536726162">"Sperimentali"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Attivare il Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Per connettere la tastiera al tablet, devi prima attivare il Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 54a9ffe..a28dc2a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"הצמדת מסך"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"עוד"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"היסטוריה"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"פיצול אופקי"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"פיצול אנכי"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"פיצול מותאם אישית"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"הצג שניות בשעון בשורת הסטטוס. פעולה זו עשויה להשפיע על אורך חיי הסוללה."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"סידור מחדש של הגדרות מהירות"</string>
     <string name="show_brightness" msgid="6613930842805942519">"הצג בהירות בהגדרות מהירות"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"אפשר דפדוף"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"הפעל דפדוף באמצעות לחצן הסקירה"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"הפעל החלפת מצב מהירה"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"אפשר זמן קצוב להפעלה במהלך הדפדוף"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"אפשר צילומי מסך במסך מלא"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"אפשר צילומי מסך במסך מלא ב\'סקירה\'"</string>
     <string name="experimental" msgid="6198182315536726162">"ניסיוניות"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"‏האם להפעיל את ה-Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"‏כדי לחבר את המקלדת לטאבלט, תחילה עליך להפעיל את ה-Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b0a1974..13217a0 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"画面固定"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>を開始できません。"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"もっと見る"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"履歴"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"横に分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"縦に分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"分割(カスタム)"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"ステータスバーに時計の秒を表示します。電池使用量に影響する可能性があります。"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"クイック設定を並べ替え"</string>
     <string name="show_brightness" msgid="6613930842805942519">"クイック設定に明るさ調整バーを表示する"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"ページ切り替えを有効にする"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"[概要] ボタンによるページ切り替えを有効にします"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"高速切り替えを有効にする"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"ページ切り替え中の起動タイムアウトを有効にします"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"全画面スクリーンショットを有効にする"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"[概要] で全画面スクリーンショットを有効にします"</string>
     <string name="experimental" msgid="6198182315536726162">"試験運用版"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"BluetoothをONにしますか?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"タブレットでキーボードに接続するには、最初にBluetoothをONにする必要があります。"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index ce8b417..c4e84a8 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ეკრანზე ჩამაგრება"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"მეტი"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ისტორია"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ჰორიზონტალური გაყოფა"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ვერტიკალური გაყოფა"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ინდივიდუალური გაყობა"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"საათის წამების ჩვენება სტატუსის ზოლში. შეიძლება გავლენა იქონიოს ბატარეაზე."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"სწრაფი პარამეტრების გადაწყობა"</string>
     <string name="show_brightness" msgid="6613930842805942519">"სიკაშკაშის ჩვენება სწრაფ პარამეტრებში"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"გვერდების გადაფურცვლის ჩართვა"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"მიმოხილვის ღილაკის მეშვეობით გვერდების გადაფურცვლის ჩართვა"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"სწრაფი გადართვის ჩართვა"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"გვერდების გადაფურცვლისას გაშვების დროის ლიმიტის ჩართვა"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"სრულეკრანიანი ეკრანის ანაბეჭდების ჩართვა"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"მიმოხილვაში სრულეკრანიანი ეკრანის ანაბეჭდების ჩართვა"</string>
     <string name="experimental" msgid="6198182315536726162">"ექსპერიმენტული"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"გსურთ Bluetooth-ის ჩართვა?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"კლავიატურის ტაბლეტთან დასაკავშირებლად, ჯერ უნდა ჩართოთ Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 586b1bf9..2133170 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"экранды бекіту"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"іздеу"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> іске қосу мүмкін болмады."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Қосымша"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Тарих"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Бөлінген көлденең"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Бөлінген тік"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Бөлінген теңшелетін"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Күйін көрсету жолағында сағат секундтарын көрсету. Батареяның қызмет көрсету мерзіміне әсер етуі мүмкін."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Жылдам параметрлерді қайта реттеу"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Жылдам параметрлерде жарықтықты көрсету"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Беттерді аудару"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"\"Шолу\" түймесі арқылы беттерді аударуды қосу"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Тез ауыстырып қосуды қосу"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Беттерді аудару кезінде іске қосуды күту уақытын қосу"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Толық экрандық скриншоттарды қосу"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"\"Шолу\" ішінде толық экрандық скриншоттарды қосу"</string>
     <string name="experimental" msgid="6198182315536726162">"Эксперименттік"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth функциясын қосу керек пе?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Пернетақтаны планшетке қосу үшін алдымен Bluetooth функциясын қосу керек."</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index f0f0d5f..6fbb325 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ការ​ភ្ជាប់​អេក្រង់"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"មិន​អាច​ចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"ច្រើនទៀត"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ប្រវត្តិ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"បំបែកផ្តេក"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"បំបែកបញ្ឈរ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"បំបែកផ្ទាល់ខ្លួន"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"បង្ហាញវិនាទីនៅលើរបារស្ថានភាពអាចនឹងប៉ះពាល់ដល់ថាមពលថ្ម។"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"រៀបចំការកំណត់រហ័សឡើងវិញ"</string>
     <string name="show_brightness" msgid="6613930842805942519">"បង្ហាញកម្រិតពន្លឺនៅក្នុងការកំណត់រហ័ស"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"បើកដំណើរការចុះទំព័រ"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"បើកដំណើការចុះទំព័រតាមរយៈប៊ូតុងទិដ្ឋភាព"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"បើកដំណើរការបិទ/បើករហ័ស"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"បើកដំណើរការអស់ពេលចាប់ផ្តើមខណៈពេលចុះទំព័រ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"បើកដំណើរការរូបថតអេក្រង់ពេញអេក្រង់"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"បើកដំណើរការរូបថតអេក្រង់ពេញអេក្រង់នៅក្នុងទិដ្ឋភាព"</string>
     <string name="experimental" msgid="6198182315536726162">"ពិសោធន៍"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"បើកប៊្លូធូសឬ?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ដើម្បីភ្ជាប់ក្តារចុចរបស់អ្នកជាមួយនឹងថេប្លេតរបស់អ្នក អ្នកត្រូវតែបើកប៊្លូធូសជាមុនសិន។"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 9dec425..c8fc91d 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ಸ್ಕ್ರೀನ್ ಪಿನ್ನಿಂಗ್"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"ಇನ್ನಷ್ಟು"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ಇತಿಹಾಸ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ಅಡ್ಡಲಾಗಿ ವಿಭಜಿಸಿದ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ಲಂಬವಾಗಿ ವಿಭಜಿಸಿದ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ಕಸ್ಟಮ್ ವಿಭಜಿಸಿದ"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಲ್ಲಿ ಗಡಿಯಾರ ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು. ಇದಕ್ಕೆ ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯು ಪರಿಣಾಮಬೀರಬಹುದು."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌‌ಗಳನ್ನು ಮರುಹೊಂದಿಸಿ"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌‌ಗಳಲ್ಲಿ ಪ್ರಖರತೆಯನ್ನು ತೋರಿಸಿ"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"ಪೇಜಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"ಸಮಗ್ರ ನೋಟದ ಬಟನ್‌ ಮೂಲಕ ಪೇಜಿಂಗ್‌ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"ವೇಗವಾಗಿ ಟಾಗಲ್‌ ಮಾಡುವಿಕೆ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"ಪೇಜಿಂಗ್ ಸಂದರ್ಭದಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆ ಕಾಲಾವಧಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"ಪೂರ್ಣ ಪರದೆ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"ಸಮಗ್ರ ನೋಟದಲ್ಲಿ ಪೂರ್ಣ ಪರದೆ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="experimental" msgid="6198182315536726162">"ಪ್ರಾಯೋಗಿಕ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡುವುದೇ?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಅನ್ನು ಟ್ಯಾಬ್ಲೆಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು, ನೀವು ಮೊದಲು ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 126d84a8..1296d21 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"화면 고정"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>을(를) 시작할 수 없습니다."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"더보기"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"기록"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"수평 분할"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"수직 분할"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"맞춤 분할"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"상태 표시줄에 시계 초 단위를 표시합니다. 배터리 수명에 영향을 줄 수도 있습니다."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"빠른 설정 재정렬"</string>
     <string name="show_brightness" msgid="6613930842805942519">"빠른 설정에서 밝기 표시"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"페이징을 사용 설정합니다."</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"최근 사용 버튼을 통해 페이징 사용"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"빠른 전환 사용"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"페이징하는 동안 실행 제한시간을 사용 설정합니다."</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"전체 화면 스크린샷을 사용 설정합니다."</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"최근 사용에서 전체 화면 스크린샷을 사용 설정합니다."</string>
     <string name="experimental" msgid="6198182315536726162">"베타"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"블루투스를 켜시겠습니까?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"키보드를 태블릿에 연결하려면 먼저 블루투스를 켜야 합니다."</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 1be6f05..ead55c7 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"экран кадоо"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"издөө"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> баштай алган жок."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Дагы"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Таржымал"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Туурасынан бөлүү"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Тигинен бөлүү"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Ыңгайлаштырылган бөлүү"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Ыкчам жөндөөлөрдү кайра коюу"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Ыкчам жөндөөлөрдөн жарык деңгээлин көрсөтүү"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Барактоону иштетүү"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Сереп баскычы менен барактоону иштетүү"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Тез которгучту иштетүү"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Барактап жатканда таймаутту иштетүү"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Толук экран скриншотторун иштетүү"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Толук экран скриншотторун Серепте иштетүү"</string>
     <string name="experimental" msgid="6198182315536726162">"Сынамык"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth күйгүзүлсүнбү?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Баскычтобуңузду планшетиңизге туташтыруу үчүн, адегенде Bluetooth\'ту күйгүзүшүңүз керек."</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 2fac9b9..c0689c3 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ການ​ປັກ​ໝຸດ​ໜ້າ​ຈໍ​"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່​ສາ​ມາດ​ເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"ເພີ່ມເຕີມ"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ປະຫວັດ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ການ​ແຍກ​ລວງ​ຂວາງ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ການ​ແຍກ​ລວງ​ຕັ້ງ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ການ​ແຍກ​ກຳ​ນົດ​ເອງ"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"ສະ​ແດງວິ​ນາ​ທີ​ໂມງ​ຢູ່​ໃນ​ແຖບ​ສະ​ຖາ​ນະ. ອາດ​ຈະ​ມີ​ຜົນ​ກະ​ທົບ​ຕໍ່​ອາ​ຍຸ​ແບັດ​ເຕີ​ຣີ."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ຈັດ​ວາງ​ການ​ຕັ້ງ​ຄ່າ​ດ່ວນ​ຄືນ​ໃໝ່"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ສະ​ແດງ​ຄວາມ​ແຈ້ງ​ຢູ່​ໃນ​ການ​ຕັ້ງ​ຄ່າ​ດ່ວນ"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"​ເປີດ​ໃຊ້​ງານ​ການ​ແບ່ງ​ໜ້າ"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"ເປີດນຳໃຊ້ການແບ່ງໜ້າຜ່ານປຸ່ມພາບລວມ"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"ເປີດນຳໃຊ້ການສັບປ່ຽນໄວ"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"​ເປີດ​ໃຊ້​ງານ​ການ​ໝົດ​ເວລາ​ການ​ເປີດ​ໃຊ້ ​ໃນ​ຂະນະ​ທີ່​ແບ່ງ​ໜ້າ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"​ເປີດ​ໃຊ້ງານພາບ​ໜ້າ​ຈໍ​ແບບ​ເຕັມ​ຈໍ"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"​ເປີດ​ໃຊ້​ງານ​ພາບ​ໜ້າ​ຈໍ​ແບບ​ເຕັມ​ຈໍ​ໃນ​ໂໝດພາບ​ລວມ"</string>
     <string name="experimental" msgid="6198182315536726162">"ຍັງຢູ່ໃນການທົດລອງ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ເປີດ​ໃຊ້ Bluetooth ບໍ່?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ເພື່ອ​ເຊື່ອມ​ຕໍ່​ແປ້ນ​ພິມ​ຂອງ​ທ່ານ​ກັບ​ແທັບ​ເລັດ​ຂອງ​ທ່ານ, ກ່ອນ​ອື່ນ​ໝົດ​ທ່ານ​ຕ້ອງ​ເປີດ Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 1533ae8d..4425d31 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekrano prisegimas"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nepavyko paleisti <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Daugiau"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Istorija"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontalus skaidymas"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikalus skaidymas"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Tinkintas skaidymas"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Rodyti laikrodžio sekundes būsenos juostoje. Tai gali paveikti akumuliatoriaus naudojimo laiką."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Pertvarkyti sparčiuosius nustatymus"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Rodyti skaistį sparčiuosiuose nustatymuose"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Įgalinti puslapių kaitą"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Įgalinti puslapių kaitą apžvalgos mygtuku"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Įgalinti greitą perjungimą"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Įgalinti paleidimo skirtąjį laiką keičiant puslapius"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Įgalinti viso ekrano kopijas"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Įgalinti viso ekrano kopijas apžvalgoje"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentinė versija"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Įjungti „Bluetooth“?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Kad galėtumėte prijungti klaviatūrą prie planšetinio kompiuterio, pirmiausia turite įjungti „Bluetooth“."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 3479320..eca57a6 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -295,6 +295,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Piespraust ekrānu"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nevarēja palaist lietotni <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Vairāk"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Vēsture"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontāls dalījums"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikāls dalījums"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Pielāgots dalījums"</string>
@@ -438,12 +440,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Statusa joslā rādīt pulksteņa sekundes. Var ietekmēt akumulatora darbības laiku."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Pārkārtot ātros iestatījumus"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Rādīt spilgtumu ātrajos iestatījumos"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Iespējot lapošanu"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Iespējot lapošanu, izmantojot pogu Pārskats"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Iespējot ātro pārslēgšanu"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Iespējot palaišanas noildzi lapošanas laikā"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Iespējot pilnekrāna ekrānuzņēmumus"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Iespējot pilnekrāna ekrānuzņēmumus sadaļā Pārskats"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentāli"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vai ieslēgt Bluetooth savienojumu?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Lai pievienotu tastatūru planšetdatoram, vispirms ir jāieslēdz Bluetooth savienojums."</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 277a519..038c669 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"прикачување екран"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пребарај"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не може да се вклучи."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Повеќе"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Историја"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Раздели хоризонтално"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Раздели вертикално"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Раздели прилагодено"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Прикажи ги секундите на часовникот на статусната лента. Може да влијае на траењето на батеријата."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Преуредете ги Брзи поставки"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Прикажете ја осветленоста во Брзи поставки"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Овозможете прелистување страници"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Овозможете прелистување страници со копчето Краток преглед"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Овозможете брзо префрлање"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Овозможете истек на време при стартување додека прелистувате страници"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Овозможете слики од цел екран"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Овозможете слики од цел екран во Преглед"</string>
     <string name="experimental" msgid="6198182315536726162">"Експериментално"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Да се вклучи Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"За да ја поврзете тастатурата со таблетот, најпрво треба да вклучите Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index a448d9b..f4964d0 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"സ്ക്രീൻ പിൻ ചെയ്യൽ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"തിരയുക"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"കൂടുതൽ"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ചരിത്രം"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"തിരശ്ചീനമായി വേർതിരിക്കുക"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ലംബമായി വേർതിരിക്കുക"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ഇഷ്‌ടാനുസൃതമായി വേർതിരിക്കുക"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"സ്റ്റാറ്റസ് ബാറിൽ ക്ലോക്ക് സെക്കൻഡ് കാണിക്കുന്നത് ബാറ്ററിയുടെ ലൈഫിനെ ബാധിക്കാം."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ദ്രുത ക്രമീകരണം പുനഃസജ്ജീകരിക്കുക"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ദ്രുത ക്രമീകരണത്തിൽ തെളിച്ചം കാണിക്കുക"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"പേജിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"ചുരുക്കവിവരണ ബട്ടൺ വഴി പേജിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"അതിവേഗ ടോഗിൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"പേജിംഗിനിടെ ലോഞ്ച് ടൈമൗട്ട് പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"പൂർണ്ണസ്ക്രീൻ സ്ക്രീൻഷോട്ടുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"ചുരുക്കവിവരണത്തിൽ പൂർണ്ണസ്ക്രീൻ സ്ക്രീൻഷോട്ടുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="experimental" msgid="6198182315536726162">"പരീക്ഷണാത്മകം!"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ഓണാക്കണോ?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"നിങ്ങളുടെ ടാബ്‌ലെറ്റുമായി കീബോർഡ് കണക്റ്റുചെയ്യുന്നതിന്, ആദ്യം Bluetooth ഓണാക്കേണ്ടതുണ്ട്."</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 8dcb6d98..122068c 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -292,6 +292,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"дэлгэц тогтоох"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж чадсангүй."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Илүү"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Түүх"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хэвтээ чиглэлд хуваах"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Босоо чиглэлд хуваах"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Хүссэн хэлбэрээр хуваах"</string>
@@ -435,12 +437,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Статус талбарт цагийн секундыг харуулах. Энэ нь тэжээлийн цэнэгт нөлөөлж болно."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Түргэн тохиргоог дахин засварлах"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Түргэн тохиргоонд гэрэлтүүлэг харах"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Өгөгдөл хадгалах/сэргээхийг идэвхжүүлэх"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Тойм товчлуурыг ашиглан өгөгдөл хадгалах/сэргээхийг идэвхжүүлэх"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Түргэн унтраах/асаахыг идэвхжүүлэх"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Өгөгдөл хадгалах/сэргээх явцад завсарлагыг эхлүүлэх"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Бүтэн дэлгэцийн дэлгэцийн агшинг идэвхжүүлэх"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Тойм хэсэгт бүтэн дэлгэцийн \"Дэлгэцийн агшинг\" идэвхжүүлэх"</string>
     <string name="experimental" msgid="6198182315536726162">"Туршилтын"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth-г асаах уу?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Компьютерийн гараа таблетад холбохын тулд эхлээд Bluetooth-г асаана уу."</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 00c4965..6415adb 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्‍क्रीन पिन करणे"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"अधिक"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"इतिहास"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज विभाजित करा"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"अनुलंब विभाजित करा"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"सानुकूल विभाजित करा"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बारमध्‍ये घड्‍याळ सेकंद दर्शवा. कदाचित बॅटरी आयुष्‍य प्रभावित होऊ शकते."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"द्रुत सेटिंग्जची पुनर्रचना करा"</string>
     <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिंग्जमध्‍ये चमक दर्शवा"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"लिखाण सक्षम करा"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"विहंगावलोकन बटणाद्वारे लिखाण सक्षम करा"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"जलद टॉगल करा सक्षम करा"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"लिखाण करताना लाँच कालबाह्य सक्षम करा"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"पूर्ण स्क्रीन स्क्रीनशॉट सक्षम करा"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"विहंगावलोकनामध्ये पूर्ण स्क्रीन स्क्रीनशॉट सक्षम करा"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रायोगिक"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटुथ सुरू करायचे?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"आपला कीबोर्ड आपल्या टॅब्लेटसह कनेक्ट करण्यासाठी, आपल्याला प्रथम ब्लूटुथ चालू करणे आवश्यक आहे."</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 7b53a6c..ceefc29 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"penyematan skrin"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulakan <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Lagi"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Sejarah"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Mendatar Terpisah"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Menegak Terpisah"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Tersuai Terpisah"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Tunjukkan saat jam dalam bar status. Mungkin menjejaskan hayat bateri."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Susun Semula Tetapan Pantas"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Tunjukkan kecerahan dalam Tetapan Pantas"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Dayakan penghalamanan"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Mendayakan penghalamanan melalui butang Ikhtisar"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Dayakan togol pantas"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Membolehkan pelancaran tamat masa semasa penghalamanan"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Dayakan tangkapan skrin skrin penuh"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Mendayakan tangkapan skrin skrin penuh dalam Ikhtisar"</string>
     <string name="experimental" msgid="6198182315536726162">"Percubaan"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Hidupkan Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Untuk menyambungkan papan kekunci anda dengan tablet, anda perlu menghidupkan Bluetooth terlebih dahulu."</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 2f52a02..81c0932 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"မျက်နှာပြင် ပင်ထိုးမှု"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"နောက်ထပ်"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"မှတ်တမ်း"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ရေပြင်ညီ ပိုင်းမည်"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ဒေါင်လိုက်ပိုင်းမည်"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"စိတ်ကြိုက် ပိုင်းမည်"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"အခြေအနေပြနေရာမှာ နာရီ စက္ကန့်များကို ပြပါ။ ဘက်ထရီ သက်တမ်းကို အကျိုးသက်ရောက်နိုင်တယ်။"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"အမြန် ဆက်တင်များကို ပြန်စီစဉ်ရန်"</string>
     <string name="show_brightness" msgid="6613930842805942519">"အမြန် ဆက်တင်များထဲက တောက်ပမှုကို ပြရန်"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"စာမျက်နှာပြောင်းမှု ဖွင့်ပါ"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"အနှစ်ချုပ်ကြည့်မှု မှတစ်ဆင့် စာမျက်နှာပြောင်းမှုကို ဖွင့်ပါ"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"အမြန်ဖွင့်/ပိတ်ခြင်း ဖွင့်ရန်"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"စာမျက်နှာပြောင်းမှု ဖွင့်တင်ရန်အတွက် ကန့်သတ်ချိန်ကို ဖွင့်ပါ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"မျက်နှာပြင်အပြည့် လျှပ်တစ်ပြက်ပုံများကို ဖွင့်ပါ"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"အနှစ်ချုပ်ကြည့်မှုထဲတွင် မျက်နှာပြင်အပြည့် လျှပ်တစ်ပြက်ပုံများကို ဖွင့်ပါ"</string>
     <string name="experimental" msgid="6198182315536726162">"စမ်းသပ်ရေး"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ဘလူးတုသ် ဖွင့်ရမလား။"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ကီးဘုတ်ကို တပ်ဘလက်နှင့် ချိတ်ဆက်ရန်၊ ပမထဦးစွာ ဘလူးတုသ်ကို ဖွင့်ပါ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 014a6b1..7f6895e 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"én-appsmodus"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kunne ikke starte <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mer"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Logg"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Del horisontalt"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Del vertikalt"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Del tilpasset"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statusfeltet på klokken. Det kan påvirke batteritiden."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Omorganiser hurtiginnstillingene"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Vis lysstyrke i hurtiginnstillingene"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Slå på paginering"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Slå på paginering via Oversikt-knappen"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Slå på hurtigveksling"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Slå på tidsavbrudd mens paginering pågår"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Slå på skjermdumper av fullskjerm"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Slå på skjermdumper av fullskjerm i Oversikt"</string>
     <string name="experimental" msgid="6198182315536726162">"På forsøksstadiet"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vil du slå på Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"For å koble tastaturet til nettbrettet ditt må du først slå på Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 46fce99..51e8a16 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रिन पिन गर्दै"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"खोजी गर्नुहोस्"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"सुरु गर्न सकिएन <xliff:g id="APP">%s</xliff:g>।"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"थप"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"इतिहास"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"तेर्सो रूपमा विभाजन गर्नुहोस्"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ठाडो रूपमा विभाजन गर्नुहोस्"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"अनुकूलन विभाजन गर्नुहोस्"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"वस्तुस्थिति पट्टीको घडीमा सेकेन्ड देखाउनुहोस्। ब्याट्री आयु प्रभावित हुन सक्छ।"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"द्रुत सेटिङहरू पुनः व्यवस्थित गर्नुहोस्"</string>
     <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिङहरूमा उज्यालो देखाउनुहोस्"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"पेजिंग सक्रिय गर्नुहोस्"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"परिदृश्य बटन मार्फत पेजिङ सक्रिय गर्नुहोस्"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"छिटो टगल सक्रिय गर्नुहोस्"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"जब पेजिंग हुन्छ टाइमआउट प्रक्षेपण सक्रिय गर्नुहोस्"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"पूर्ण स्क्रिन स्क्रीनशटहरू सक्रिय गर्नुहोस्"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"परिदृश्यमा पूर्ण स्क्रिन स्क्रीनशटहरू सक्रिय गर्नुहोस्"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रयोगात्मक"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लुटुथ सक्रिय पार्ने हो?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"आफ्नो ट्याब्लेटसँग किबोर्ड जोड्न, पहिले तपाईँले ब्लुटुथ सक्रिय गर्नुपर्छ।"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index dbcaab8..88d0b4b 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -283,7 +283,7 @@
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Meldingen"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zaklamp"</string>
     <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobiele gegevens"</string>
-    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Gegevensgebruik"</string>
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datagebruik"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Resterende gegevens"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Limiet overschreden"</string>
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> gebruikt"</string>
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"scherm vastzetten"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kan <xliff:g id="APP">%s</xliff:g> niet starten."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Meer"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Geschiedenis"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontaal splitsen"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Verticaal splitsen"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Aangepast splitsen"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Klokseconden op de statusbalk weergeven. Kan van invloed zijn op de accuduur."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Snelle instellingen opnieuw indelen"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Helderheid weergeven in Snelle instellingen"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Paginering inschakelen"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Paginering via de knop Overzicht inschakelen"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Snel schakelen inschakelen"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Starttime-out tijdens paginering inschakelen"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Screenshots op volledig scherm inschakelen"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Screenshots op volledig scherm in Overzicht inschakelen"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimenteel"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth inschakelen?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Als je je toetsenbord wilt verbinden met je tablet, moet je eerst Bluetooth inschakelen."</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 5f21e94..df6c473af 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ਸਕ੍ਰੀਨ ਪਿਨਿੰਗ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ਖੋਜੋ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"ਹੋਰ"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ਇਤਿਹਾਸ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ਵਰਟੀਕਲ ਸਪਲਿਟ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ਕਸਟਮ ਸਪਲਿਟ"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"ਸਥਿਤੀ ਬਾਰ ਵਿੱਚ ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ। ਬੈਟਰੀ ਸਮਰੱਥਾ ਤੇ ਅਸਰ ਪੈ ਸਕਦਾ ਹੈ।"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਦੁਬਾਰਾ ਕ੍ਰਮ ਦਿਓ"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਮਕ ਦਿਖਾਓ"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"ਪੇਜਿੰਗ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"ਰੂਪ-ਰੇਖਾ ਬਟਨ ਦੁਆਰਾ ਪੇਜਿੰਗ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"ਤੇਜ਼ ਬਦਲੋ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"ਪੇਜਿੰਗ ਦੌਰਾਨ ਲਾਂਚ ਸਮਾਂ ਸਮਾਪਤੀ ਦੀ ਮਿਅਾਦ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"ਪੂਰੀ-ਸਕਰੀਨ ਸਕਰੀਨਸ਼ਾਟ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"ਰੂਪ-ਰੇਖਾ ਵਿੱਚ ਪੂਰੀ-ਸਕਰੀਨ ਸਕਰੀਨਸ਼ਾਟ ਨੂੰ ਯੋਗ ਬਣਾਓ"</string>
     <string name="experimental" msgid="6198182315536726162">"ਪ੍ਰਯੋਗਾਤਮਿਕ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ਚਾਲੂ ਕਰੋ?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ਆਪਣੇ ਟੈਬਲੇਟ ਨਾਲ ਆਪਣਾ ਕੀ-ਬੋਰਡ ਕਨੈਕਟ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਪਹਿਲਾਂ Bluetooth ਚਾਲੂ ਕਰਨ ਦੀ ਜ਼ਰੂਰਤ ਹੈ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 68816ef..694132b 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"przypinanie ekranu"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nie udało się uruchomić aplikacji <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Więcej"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historia"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podziel poziomo"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podziel pionowo"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Podziel niestandardowo"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Pokaż sekundy na zegarku na pasku stanu. Może mieć wpływ na czas pracy baterii."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Uporządkuj Szybkie ustawienia"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Pokaż jasność w Szybkich ustawieniach"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Włącz stronicowanie"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Włącz stronicowanie za pomocą przycisku Przegląd"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Włącz szybkie przełączanie"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Włącz limit czasu uruchomienia podczas stronicowania"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Włącz pełnoekranowe zrzuty ekranu"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Włącz pełnoekranowe zrzuty ekranu w widoku Przegląd"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperymentalne"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Włączyć Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Aby połączyć klawiaturę z tabletem, musisz najpierw włączyć Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index c875922..e806bfc 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mais"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Histórico"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de status. Pode afetar a duração da bateria."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar \"Configurações rápidas\""</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar brilho nas \"Configurações rápidas\""</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Ativar paginação"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Ativar paginação pelo botão \"Visão geral\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Ativar alternância rápida"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Ativar tempo limite de inicialização ao fazer paginação"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Ativar capturas de tela em tela cheia"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Ativar capturas de tela em tela cheia em \"Visão geral\""</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentais"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Ativar o Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar o teclado ao tablet, é preciso primeiro ativar o Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1594dca..468c75d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação no ecrã"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar o <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mais"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Histórico"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string>
@@ -437,12 +439,6 @@
     <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 as Definições rápidas"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar luminosidade nas Definições rápidas"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Ativar a paginação"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Ativar a paginação através do botão Vista geral"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Ativar alternância rápida"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Ativar o limite de tempo de lançamento durante a paginação"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Ativar capturas de ecrã inteiro"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Ativar capturas de ecrã inteiro na Vista geral"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Pretende ativar o Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para ligar o teclado ao tablet, tem de ativar primeiro o Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c875922..e806bfc 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mais"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Histórico"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de status. Pode afetar a duração da bateria."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar \"Configurações rápidas\""</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostrar brilho nas \"Configurações rápidas\""</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Ativar paginação"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Ativar paginação pelo botão \"Visão geral\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Ativar alternância rápida"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Ativar tempo limite de inicialização ao fazer paginação"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Ativar capturas de tela em tela cheia"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Ativar capturas de tela em tela cheia em \"Visão geral\""</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentais"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Ativar o Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar o teclado ao tablet, é preciso primeiro ativar o Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index ab182a2..1b8e8de 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -295,6 +295,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixare pe ecran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nu a putut porni."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mai mult"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Istoric"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divizare pe orizontală"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divizare pe verticală"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divizare personalizată"</string>
@@ -438,12 +440,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Afișează secundele pe ceas în bara de stare. Poate afecta autonomia bateriei."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Rearanjați Setările rapide"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Afișați luminozitatea în Setările rapide"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Activați paginarea"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Activați paginarea prin butonul Recente"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Activați comutarea rapidă"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Activați timpul limită pentru lansare în timpul paginării"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Activați capturile de ecran pe ecran complet"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Activați capturile de ecran pe ecran complet în modul Prezentare generală"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentale"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Activați Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Pentru a conecta tastatura la tabletă, mai întâi trebuie să activați Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ecacd4b..9068e0b 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Заблокировать в приложении"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не удалось запустить приложение \"<xliff:g id="APP">%s</xliff:g>\""</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Ещё"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Журнал"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Разделить по горизонтали"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Разделить по вертикали"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Разделить по-другому"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Показывать в строке состояния время с точностью до секунды (заряд батареи может расходоваться быстрее)."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Изменить порядок Быстрых настроек"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Добавить яркость в Быстрые настройки"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Включить подкачку страниц"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Разрешить подкачку страниц с помощью кнопки \"Обзор\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Быстрое переключение"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Включить тайм-аут запуска при подкачке страниц"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Разрешить скриншоты всего экрана"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Разрешить скриншоты всего экрана в режиме обзора"</string>
     <string name="experimental" msgid="6198182315536726162">"Экспериментальная функция"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Подключение по Bluetooth"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Чтобы подключить клавиатуру к планшету, включите Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index a8f9469..3be3718 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"තිර ඇමිණීම"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"සෙවීම"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැක."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"තවත්"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ඉතිහාසය"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"තිරස්ව වෙන් කරන්න"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"සිරස්ව වෙන් කරන්න"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"අභිමත ලෙස වෙන් කරන්න"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"තත්ත්ව තීරුවෙහි ඔරලෝසු තත්පර පෙන්වන්න. බැටරි ආයු කාලයට බලපෑමට හැකිය."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"ඉක්මන් සැකසීම් යළි පිළිවෙළට සකසන්න"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ඉක්මන් සැකසීම්වල දීප්තිය පෙන්වන්න"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"පේජින් සබල කිරීම"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"දළ විශ්ලේෂණ බොත්තම හරහා පේජින් සබල කිරීම"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"වේගවත් ටොගල කිරීම සබල කරන්න"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"පේජින් අතරතුර දියත් කිරීමේ කාල නිමාව සබල කිරීම"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"පූර්ණ තිරයේ තිර රූ සබල කිරීම"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"දළ විශ්ලේෂණය තුළ පූර්ණ තිරයේ තිර රූ සබල කිරීම"</string>
     <string name="experimental" msgid="6198182315536726162">"පරීක්ෂණාත්මක"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"බ්ලූටූත් ක්‍රියාත්මක කරන්නද?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ඔබේ යතුරු පුවරුව ඔබේ ටැබ්ලට් පරිගණකයට සම්බන්ධ කිරීමට, ඔබ පළමුව බ්ලූටූත් ක්‍රියාත්මක කළ යුතුය."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index bd7e210..d96194c 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripnutie k obrazovke"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikáciu <xliff:g id="APP">%s</xliff:g> sa nepodarilo spustiť"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Viac"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"História"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Rozdeliť vodorovné"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Rozdeliť zvislé"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Rozdeliť vlastné"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Zobrazí sekundy v stavovom riadku. Môže to ovplyvňovať výdrž batérie."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Zmeniť usporiadanie Rýchlych nastavení"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Zobraziť jas v Rýchlych nastaveniach"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Povoliť prechádzanie po stranách"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Povoľte prechádzanie po stranách prostredníctvom tlačidla Prehľad"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Povoliť rýchle prepínanie"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Povolenie časového limitu pre spustenie počas prechádzania po stranách"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Povoliť snímky celej obrazovky"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Povolenie snímok celej obrazovky v Prehľade"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentálne"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Zapnúť Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ak chcete klávesnicu pripojiť k tabletu, najprv musíte zapnúť Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 6d7fbc0..f3d3b39 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripenjanje zaslona"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacije <xliff:g id="APP">%s</xliff:g> ni bilo mogoče zagnati."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Več"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Zgodovina"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Razdeli vodoravno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Razdeli navpično"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Razdeli po meri"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikaže sekunde pri uri v vrstici stanja. To lahko vpliva na čas delovanja pri akumulatorskem napajanju."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Preuredi hitre nastavitve"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Prikaz svetlosti v hitrih nastavitvah"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Omogočanje pregleda strani"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Omogoči pregled strani z gumbom za pregled"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Omogoči hiter preklop"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Omogoči potek časovne omejitve za odpiranje med pregledom strani"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Omogočanje celozaslonskih posnetkov zaslona"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Omogoči celozaslonske posnetke zaslona v Pregledu"</string>
     <string name="experimental" msgid="6198182315536726162">"Poskusno"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Želite vklopiti Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Če želite povezati tipkovnico in tablični računalnik, vklopite Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 38066be..afad772 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"gozhdimi i ekranit"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"kërko"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nuk mundi të nisej."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Më shumë"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historiku"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Ndaje horizontalisht"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Ndaj vertikalisht"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Ndaj të personalizuarën"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te jeta e baterisë."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Risistemo Cilësimet e shpejta"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Shfaq ndriçimin te Cilësimet e shpejta"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Aktivizo shfletimin"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Aktivizo shfletimin me butonin \"Përmbledhja\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Aktivizo ndërrimin e shpejtë"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Aktivizo kohën e pritjes të nisjes gjatë shfletimit"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Aktivizo pamjet e ekranit në ekranin e plotë"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Aktivizo pamjet e ekranit në ekranin e plotë te \"Përmbledhja\""</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentale"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Të aktivizohet \"bluetooth-i\"?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Për të lidhur tastierën me tabletin, në fillim duhet të aktivizosh \"bluetooth-in\"."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5fd78f0..ad14d26 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -295,6 +295,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"качење екрана"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Покретање апликације <xliff:g id="APP">%s</xliff:g> није успело."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Још"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Историја"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Подели хоризонтално"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Подели вертикално"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Прилагођено дељење"</string>
@@ -438,12 +440,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Секунде на сату се приказују на статусној траци. То може да утиче на трајање батерије."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Преуреди Брза подешавања"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Прикажи осветљеност у Брзим подешавањима"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Омогући листање"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Омогућава листање помоћу дугмета Преглед"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Омогући брзо листање"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Омогућава временско ограничење покретања при листању"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Омогући снимке екрана преко целог екрана"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Омогућава снимке екрана преко целог екрана у Прегледу"</string>
     <string name="experimental" msgid="6198182315536726162">"Експериментално"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Желите ли да укључите Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Да бисте повезали тастатуру са таблетом, прво морате да укључите Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index bec7593..15e8b12 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fästa skärmen"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Det gick inte att starta appen <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Mer"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historik"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dela horisontellt"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Dela vertikalt"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Dela anpassad"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Visa klocksekunder i statusfältet. Detta kan påverka batteritiden."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Ordna snabbinställningarna"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Visa ljusstyrka i snabbinställningarna"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Aktivera sidindelning"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Aktivera sidindelning via knappen Översikt"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Aktivera snabb aktivering och inaktivering"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Aktivera timeout i lanseringen vid sidindelning"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Aktivera skärmdumpar på helskärm"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Aktivera skärmdumpar på helskärm i översikten"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimentella"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vill du aktivera Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Om du vill ansluta tangentbordet till surfplattan måste du först aktivera Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 8cc6712..1d231fc 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kudumisha programu moja"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Zaidi"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Historia"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gawanya Mlalo"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Gawanya Wima"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Maalum Iliyogawanywa"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Onyesha sekunde za saa katika sehemu ya arifa. Inaweza kuathiri muda wa matumizi ya betri."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Panga Upya Mipangilio ya Haraka"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Onyesha unga\'avu katika Mipangilio ya Haraka"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Washa kipengee cha kupata kumbukumbu"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Washa kipengee cha kupata kumbukumbu kupitia kitufe cha Muhtasari"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Washa kugeuza haraka"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Washa kipengee cha kuisha kwa muda wa uzinduzi unapopata kumbukumbu"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Washa picha za skrini nzima"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Washa picha za skrini nzima katika Muhtasari"</string>
     <string name="experimental" msgid="6198182315536726162">"Ya majaribio"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Je, ungependa kuwasha Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ili uunganishe Kibodi yako kwenye kompyuta yako kibao, lazima kwanza uwashe Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 5896c3001..c41494b 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"திரையை பின் செய்தல்"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"தேடு"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ஐத் தொடங்க முடியவில்லை."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"மேலும்"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"வரலாறு"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"கிடைமட்டமாகப் பிரி"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"செங்குத்தாகப் பிரி"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"தனிவிருப்பத்தில் பிரி"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"நிலைப் பட்டியில் கடிகார வினாடிகளைக் காட்டும். பேட்டரியின் ஆயுளைக் குறைக்கலாம்."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"விரைவு அமைப்புகளை மறுவரிசைப்படுத்து"</string>
     <string name="show_brightness" msgid="6613930842805942519">"விரைவு அமைப்புகளில் ஒளிர்வுப் பட்டியைக் காட்டு"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"பேஜிங்கை இயக்கு"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"மேலோட்டப் பார்வை பொத்தான் வழியாக பேஜிங்கை இயக்கு"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"வேகமாக மாறுவதை இயக்கு"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"பேஜிங்கின் போது தொடக்க நேர முடிவை இயக்கு"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"முழுத்திரை ஸ்கிரீன் ஷாட்களை இயக்கு"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"மேலோட்டப் பார்வையில் முழுத்திரை ஸ்கிரீன் ஷாட்களை இயக்கு"</string>
     <string name="experimental" msgid="6198182315536726162">"சோதனை முயற்சி"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"புளூடூத்தை இயக்கவா?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"உங்கள் டேப்லெட்டுடன் விசைப்பலகையை இணைக்க, முதலில் புளூடூத்தை இயக்க வேண்டும்."</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index dccac8b..a628ef7 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"స్క్రీన్ పిన్నింగ్"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"మరింత"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"చరిత్ర"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"సమతలంగా విభజించు"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"లంబంగా విభజించు"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"అనుకూలంగా విభజించు"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"స్థితి పట్టీలో గడియారం సెకన్లు చూపుతుంది. బ్యాటరీ శక్తి ప్రభావితం చేయవచ్చు."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"శీఘ్ర సెట్టింగ్‌ల ఏర్పాటు క్రమం మార్చు"</string>
     <string name="show_brightness" msgid="6613930842805942519">"శీఘ్ర సెట్టింగ్‌ల్లో ప్రకాశం చూపు"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"పేజింగ్‌ను ప్రారంభించు"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"స్థూలదృష్టి బటన్ ద్వారా పేజింగ్‌ను ప్రారంభిస్తుంది"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"వేగవంతమైన టోగుల్‌ను ప్రారంభించు"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"పేజింగ్ చేస్తున్నప్పుడు గడువు ముగింపు లాంచ్ చేయిని ప్రారంభిస్తుంది"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"పూర్తి స్క్రీన్ స్క్రీన్‌షాట్‌లను ప్రారంభించండి"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"స్థూలదృష్టిలో పూర్తి స్క్రీన్ స్క్రీన్‌షాట్‌లను ప్రారంభిస్తుంది"</string>
     <string name="experimental" msgid="6198182315536726162">"ప్రయోగాత్మకం"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"బ్లూటూత్ ఆన్ చేయాలా?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"మీ కీబోర్డ్‌ను మీ టాబ్లెట్‌తో కనెక్ట్ చేయడానికి, మీరు ముందుగా బ్లూటూత్ ఆన్ చేయాలి."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 625b676..44ad1fa 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"การตรึงหน้าจอ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"ไม่สามารถเริ่มใช้ <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"เพิ่มเติม"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"ประวัติ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"แยกในแนวนอน"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"แยกในแนวตั้ง"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"แยกแบบกำหนดเอง"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"แสดงวินาทีของนาฬิกาในแถบสถานะ อาจส่งผลต่ออายุแบตเตอรี"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"จัดเรียงการตั้งค่าด่วนใหม่"</string>
     <string name="show_brightness" msgid="6613930842805942519">"แสดงความสว่างในการตั้งค่าด่วน"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"เปิดใช้การสลับหน้า"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"เปิดใช้การสลับหน้าผ่านทางปุ่มภาพรวม"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"เปิดใช้การสลับแบบด่วน"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"เปิดใช้ระยะหมดเวลาการเปิดขณะสลับหน้า"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"เปิดใช้ภาพหน้าจอแบบเต็มจอ"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"เปิดใช้ภาพหน้าจอแบบเต็มจอใน \"ภาพรวม\""</string>
     <string name="experimental" msgid="6198182315536726162">"ทดสอบ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"เปิดบลูทูธไหม"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"หากต้องการเชื่อมต่อแป้นพิมพ์กับแท็บเล็ต คุณต้องเปิดบลูทูธก่อน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e3b8e24..c1bb85c 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pagpi-pin sa screen"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Hindi masimulan <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Higit pa"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"History"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Custom"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Ipakita ang mga segundo ng orasan sa status bar. Maaaring makaapekto sa tagal ng baterya."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Ayusing Muli ang Mga Mabilisang Setting"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Ipakita ang liwanag sa Mga Mabilisang Setting"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"I-enable ang paging"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"I-enable ang paging sa pamamagitan ng button na Pangkalahatang-ideya"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"I-enable ang mabilis na pag-toggle"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"I-enable ang pag-timeout ng paglunsad habang nagsasagawa ng paging"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"I-enable ang mga fullscreen na screenshot"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"I-enable ang mga fullscreen na screenshot sa Pangkalahatang-ideya"</string>
     <string name="experimental" msgid="6198182315536726162">"Pang-eksperimento"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"I-on ang Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Upang ikonekta ang iyong keyboard sa iyong tablet, kailangan mo munang i-on ang Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 2fe49e5..854f850 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekran sabitleme"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlatılamadı."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Diğer"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Geçmiş"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Yatay Ayırma"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Dikey Ayırma"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Özel Ayırma"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Durum çubuğunda saatin saniyelerini gösterir. Pil ömrünü etkileyebilir."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Hızlı Ayarlar\'ı Yeniden Düzenle"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Hızlı Ayarlar\'da parlaklığı göster"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Sayfalara ayırmayı etkinleştir"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Genel bakış düğmesiyle sayfalara ayırmayı etkinleştirin"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Hızlı açma/kapatmayı etkinleştir"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Sayfalara ayırma sırasında başlatma zaman aşımını etkinleştirin"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Tam ekran boyutunda ekran görüntülerini etkinleştir"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Genel bakışta tam ekran boyutundaki ekran görüntülerini etkinleştirin"</string>
     <string name="experimental" msgid="6198182315536726162">"Deneysel"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth açılsın mı?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Klavyenizi tabletinize bağlamak için önce Bluetooth\'u açmanız gerekir."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5a749c4..5347d93 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -296,6 +296,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"закріпити екран"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не вдалося запустити <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Більше"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Історія"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Розділити горизонтально"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Розділити вертикально"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Розділити (власний варіант)"</string>
@@ -439,12 +441,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Показувати секунди на годиннику в рядку стану. Акумулятор може розряджатися швидше."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Упорядкувати швидкі налаштування"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Показувати панель яскравості у швидких налаштуваннях"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Увімкнути перехід між сторінками"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Увімкнути перехід між сторінками за допомогою кнопки \"Огляд\""</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Увімкнути швидкий перехід"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Увімкнути очікування на запуск під час переходу на сторінку"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Увімкнути знімки повного екрана"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Увімкнути знімки повного екрана в режимі огляду"</string>
     <string name="experimental" msgid="6198182315536726162">"Експериментальні налаштування"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Увімкнути Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Щоб під’єднати клавіатуру до планшета, спершу потрібно ввімкнути Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 7dcb076..b9da6e3 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"اسکرین کو پن کرنا"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"تلاش کریں"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> کو شروع نہیں کیا جا سکا۔"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"مزید"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"سرگزشت"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"بلحاظ افقی الگ کریں"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"بلحاظ عمودی الگ کریں"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"بلحاظ حسب ضرورت الگ کریں"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"گھڑی کے سیکنڈز اسٹیٹس بار میں دکھائیں۔ اس کا بیٹری کی زندگی پر اثر پڑ سکتا ہے۔"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"فوری ترتیبات کو دوبارہ ترتیب دیں"</string>
     <string name="show_brightness" msgid="6613930842805942519">"فوری ترتیبات میں چمکیلا پن دکھائیں"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"پیجنگ فعال کریں"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"مجموعی جائزہ بٹن کے ذریعے پیجنگ فعال کریں"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"تیز ٹوگل فعال کریں"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"پیجنگ کے دوران لانچ ٹائم آؤٹ فعال کریں"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"فل اسکرین کے اسکرین شاٹس فعال کریں"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"مجموعی جائزے میں فل اسکرین کے اسکرین شاٹس فعال کریں"</string>
     <string name="experimental" msgid="6198182315536726162">"تجرباتی"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"بلوٹوتھ آن کریں؟"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"اپنے کی بورڈ کو اپنے ٹیبلٹ کے ساتھ منسلک کرنے کیلئے پہلے آپ کو اپنا بلو ٹوتھ آن کرنا ہو گا۔"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 1f26da6..67cd123 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"o‘zgarmas ekran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Ko‘proq"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Jurnal"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gorizontal yo‘nalishda bo‘lish"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikal yo‘nalishda bo‘lish"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Boshqa usulda bo‘lish"</string>
@@ -437,12 +439,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="overview_page_on_toggle" msgid="7332906295136546986">"Sahifalashni yoqish"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Umumiy ma’lumot tugmasi orqali sahifalashni yoqish"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Tezkor almashtirishni yoqish"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Sahifalashda tanaffusni yoqish"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"To‘liq ekranni skrinshotga olishni yoqish"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Umumiy rejimda to‘liq ekranni skrinshotga olishni yoqish"</string>
     <string name="experimental" msgid="6198182315536726162">"Tajribaviy"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth yoqilsinmi?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Klaviaturani planshetingizga ulash uchun Bluetooth xizmatini yoqishingiz kerak."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 41ecb45..aa81068 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"khóa màn hình"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Không thể khởi động <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Thêm"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Lịch sử"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Phân tách ngang"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Phân tách dọc"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Tùy chỉnh phân tách"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Hiển thị giây đồng hồ trong thanh trạng thái. Có thể ảnh hưởng đến thời lượng pin."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Sắp xếp lại Cài đặt nhanh"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Hiển thị độ sáng trong Cài đặt nhanh"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Bật đánh số trang"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Bật đánh số trang qua nút Tổng quan"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Bật chuyển đổi nhanh"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Bật thời gian chờ khởi chạy trong khi đánh số trang"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Bật ảnh chụp toàn màn hình"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Bật ảnh chụp toàn màn hình trong Tổng quan"</string>
     <string name="experimental" msgid="6198182315536726162">"Thử nghiệm"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bật Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Để kết nối bàn phím với máy tính bảng, trước tiên, bạn phải bật Bluetooth."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cc78ef7..fa69975 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"固定屏幕"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"无法启动<xliff:g id="APP">%s</xliff:g>。"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"更多"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"历史记录"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"垂直分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"自定义分割"</string>
@@ -437,17 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"在状态栏中显示时钟的秒数。这可能会影响电池的续航时间。"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"重新排列快速设置"</string>
     <string name="show_brightness" msgid="6613930842805942519">"在快速设置中显示亮度栏"</string>
-    <!-- no translation found for overview_page_on_toggle (7332906295136546986) -->
-    <skip />
-    <!-- no translation found for overview_page_on_toggle_desc (3350421878356386241) -->
-    <skip />
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"启用快速切换"</string>
-    <!-- no translation found for overview_fast_toggle_via_button_desc (8983671478896649561) -->
-    <skip />
-    <!-- no translation found for overview_fullscreen_thumbnails (3052584848522856237) -->
-    <skip />
-    <!-- no translation found for overview_fullscreen_thumbnails_desc (3588874352141119692) -->
-    <skip />
     <string name="experimental" msgid="6198182315536726162">"实验性"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"要开启蓝牙吗?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"要将您的键盘连接到平板电脑,您必须先开启蓝牙。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 1a02914..7375a92 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"更多"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"記錄"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"垂直分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"自訂分割"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"在狀態列中顯示時鐘秒數,但可能會影響電池壽命。"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"重新排列快速設定"</string>
     <string name="show_brightness" msgid="6613930842805942519">"在快速設定顯示亮度"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"啟用分頁"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"透過「概覽」按鈕啟用分頁"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"啟用快速切換"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"進行分頁時啟用啟動逾時"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"啟用全螢幕擷取畫面"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"在「概覽」啟用全螢幕擷取畫面"</string>
     <string name="experimental" msgid="6198182315536726162">"實驗版"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"要開啟藍牙嗎?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"如要將鍵盤連接至平板電腦,請先開啟藍牙。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 659334d..5edda84 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"更多"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"紀錄"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"垂直分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"自訂分割"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"在狀態列中顯示時鐘秒數。這可能會影響電池續航力。"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"重新排列快速設定"</string>
     <string name="show_brightness" msgid="6613930842805942519">"在快速設定中顯示亮度"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"啟用分頁功能"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"啟用透過 [總覽] 按鈕切換分頁的功能"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"啟用快速切換"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"切換分頁時啟用啟動逾時功能"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"啟用全螢幕的螢幕擷取畫面"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"在「總覽」畫面中啟用全螢幕的螢幕擷取畫面"</string>
     <string name="experimental" msgid="6198182315536726162">"實驗性"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"要開啟藍牙功能嗎?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"如要將鍵盤連線到平板電腦,您必須先開啟藍牙。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 8ba9363..51c4389 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -294,6 +294,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ukuphina isikrini"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ayikwazanga ukuqala i-<xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_show_history_button_label" msgid="7062088196449747245">"Okuningi"</string>
+    <string name="recents_history_label" msgid="3076213823382198287">"Umlando"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Hlukanisa okuvundlile"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Hlukanisa okumile"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Hlukanisa kwezifiso"</string>
@@ -437,12 +439,6 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Bonisa amasekhondi wewashi kubha yesimo. Ingathinta impilo yebhethri."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Hlela kabusha izilungiselelo ezisheshayo"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Bonisa ukukhanya kuzilungiselelo ezisheshayo"</string>
-    <string name="overview_page_on_toggle" msgid="7332906295136546986">"Nika amandla ukuphenya"</string>
-    <string name="overview_page_on_toggle_desc" msgid="3350421878356386241">"Nika amandla wenkinobho yokubuka konke"</string>
-    <string name="overview_fast_toggle_via_button" msgid="8316769524084143500">"Nika amandla ukuguqula ngokushesha"</string>
-    <string name="overview_fast_toggle_via_button_desc" msgid="8983671478896649561">"Nika amandla ukuvula kokuphela kwesikhathi ngesikhathi uphenya"</string>
-    <string name="overview_fullscreen_thumbnails" msgid="3052584848522856237">"Nika amandla izithombe-skrini ezigcwele"</string>
-    <string name="overview_fullscreen_thumbnails_desc" msgid="3588874352141119692">"Nika amandla izithombe-skrini ezigcwele ngokubuka konke"</string>
     <string name="experimental" msgid="6198182315536726162">"Okokulinga"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vula i-Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ukuze uxhume ikhibhodi yakho nethebhulethi yakho, kufanele uqale ngokuvula i-Bluetooth."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c85ada8..82192fe 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -214,9 +214,6 @@
     <!-- The amount to offset when animating into an affiliate group. -->
     <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen>
 
-    <!-- The alpha to apply to a task thumbnail. -->
-    <item name="recents_task_view_thumbnail_alpha" format="float" type="dimen">0.9</item>
-
     <!-- The height of a task view bar. -->
     <dimen name="recents_task_bar_height">56dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index 96ee397..d931856 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -180,7 +180,7 @@
         mProfileManager = bluetoothManager.getProfileManager();
         bluetoothManager.getEventManager().registerCallback(new BluetoothCallbackHandler());
 
-        InputManager im = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
+        InputManager im = context.getSystemService(InputManager.class);
         im.registerOnTabletModeChangedListener(this, mHandler);
         mInTabletMode = im.isInTabletMode();
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 94c45a4..a0c481a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -724,18 +724,6 @@
         getResizeTaskDebugDialog().showResizeTaskDialog(event.task, mRecentsView);
     }
 
-    public final void onBusEvent(DragStartEvent event) {
-        // Lock the orientation while dragging
-        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
-
-        // TODO: docking requires custom accessibility actions
-    }
-
-    public final void onBusEvent(DragEndEvent event) {
-        // Unlock the orientation when dragging completes
-        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_BEHIND);
-    }
-
     public final void onBusEvent(LaunchTaskSucceededEvent event) {
         MetricsLogger.histogram(this, "overview_task_launch_index", event.taskIndexFromStackFront);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java
index 957da94..3deeb47 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java
@@ -19,7 +19,6 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.model.Task;
-import com.android.systemui.recents.views.DragView;
 import com.android.systemui.recents.views.DropTarget;
 import com.android.systemui.recents.views.TaskView;
 
@@ -30,15 +29,13 @@
 
     public final Task task;
     public final TaskView taskView;
-    public final DragView dragView;
     public final DropTarget dropTarget;
     public final ReferenceCountedTrigger postAnimationTrigger;
 
-    public DragEndEvent(Task task, TaskView taskView, DragView dragView, DropTarget dropTarget,
+    public DragEndEvent(Task task, TaskView taskView, DropTarget dropTarget,
             ReferenceCountedTrigger postAnimationTrigger) {
         this.task = task;
         this.taskView = taskView;
-        this.dragView = dragView;
         this.dropTarget = dropTarget;
         this.postAnimationTrigger = postAnimationTrigger;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java
index 2d42a0e..b81c10c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java
@@ -16,9 +16,9 @@
 
 package com.android.systemui.recents.events.ui.dragndrop;
 
+import android.graphics.Point;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.model.Task;
-import com.android.systemui.recents.views.DragView;
 import com.android.systemui.recents.views.TaskView;
 
 /**
@@ -28,11 +28,11 @@
 
     public final Task task;
     public final TaskView taskView;
-    public final DragView dragView;
+    public final Point tlOffset;
 
-    public DragStartEvent(Task task, TaskView taskView, DragView dragView) {
+    public DragStartEvent(Task task, TaskView taskView, Point tlOffset) {
         this.task = task;
         this.taskView = taskView;
-        this.dragView = dragView;
+        this.tlOffset = tlOffset;
     }
 }
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 59fb6cf..2b20c07 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -410,7 +410,7 @@
             return thumbnail;
         }
 
-        Bitmap thumbnail = SystemServicesProxy.getThumbnail(mAm, taskId);
+        Bitmap thumbnail = getThumbnail(taskId);
         if (thumbnail != null) {
             thumbnail.setHasAlpha(false);
             // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
@@ -430,8 +430,12 @@
     /**
      * Returns a task thumbnail from the activity manager
      */
-    public static Bitmap getThumbnail(ActivityManager activityManager, int taskId) {
-        ActivityManager.TaskThumbnail taskThumbnail = activityManager.getTaskThumbnail(taskId);
+    public Bitmap getThumbnail(int taskId) {
+        if (mAm == null) {
+            return null;
+        }
+
+        ActivityManager.TaskThumbnail taskThumbnail = mAm.getTaskThumbnail(taskId);
         if (taskThumbnail == null) return null;
 
         Bitmap thumbnail = taskThumbnail.mainThumbnail;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 5921d13..3bb89a3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -128,7 +128,7 @@
             boolean isStackTask = true;
             if (debugFlags.isHistoryEnabled()) {
                 boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId);
-                isStackTask = !isFreeformTask && (!isHistoricalTask(t) ||
+                isStackTask = isFreeformTask || (!isHistoricalTask(t) ||
                         (t.lastActiveTime >= lastStackActiveTime &&
                                 i >= (taskCount - MIN_NUM_TASKS)));
                 if (isStackTask && newLastStackActiveTime < 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 945fdc1..271a2a0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import android.animation.ObjectAnimator;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.util.IntProperty;
@@ -65,6 +64,15 @@
         mCornerRadius = cornerRadius;
     }
 
+    /**
+     * Resets the right and bottom clip for this view.
+     */
+    public void reset() {
+        mClipRect.setEmpty();
+        mSourceView.invalidateOutline();
+        updateClipBounds();
+    }
+
     @Override
     public void getOutline(View view, Outline outline) {
         outline.setAlpha(mMinAlpha + mAlpha / (1f - mMinAlpha));
@@ -82,15 +90,6 @@
         }
     }
 
-    /**
-     * Animates the bottom clip.
-     */
-    public void animateClipBottom(int bottom) {
-        ObjectAnimator animator = ObjectAnimator.ofInt(this, CLIP_BOTTOM, getClipBottom(), bottom);
-        animator.setDuration(150);
-        animator.start();
-    }
-
     /** Sets the bottom clip. */
     public void setClipBottom(int bottom, boolean force) {
         if (bottom != mClipRect.bottom || force) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DragView.java b/packages/SystemUI/src/com/android/systemui/recents/views/DragView.java
deleted file mode 100644
index 96dfaac..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/DragView.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 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.recents.views;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.widget.ImageView;
-
-public class DragView extends ImageView {
-
-    // The offset from the top-left of the dragBitmap
-    Point mTopLeftOffset;
-
-    public DragView(Context context, Bitmap dragBitmap, Point tlOffset) {
-        super(context);
-
-        mTopLeftOffset = tlOffset;
-        setImageBitmap(dragBitmap);
-    }
-
-    public Point getTopLeftOffset() {
-        return mTopLeftOffset;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 90d62c1..a70b66d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.views;
 
+import android.graphics.Rect;
 import android.util.Log;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
@@ -52,8 +53,8 @@
         int numFreeformTasks = stackLayout.mNumFreeformTasks;
         if (!freeformTasks.isEmpty()) {
             // Calculate the cell width/height depending on the number of freeform tasks
-            mFreeformCellXCount = Math.max(2, (int) Math.ceil(Math.sqrt(numFreeformTasks)));
-            mFreeformCellYCount = Math.max(2, (int) Math.ceil((float) numFreeformTasks /
+            mFreeformCellXCount = Math.max(1, (int) Math.ceil(Math.sqrt(numFreeformTasks)));
+            mFreeformCellYCount = Math.max(1, (int) Math.ceil((float) numFreeformTasks /
                     mFreeformCellXCount));
             // For now, make the cells square
             mFreeformCellWidth = Math.min(stackLayout.mFreeformRect.width() / mFreeformCellXCount,
@@ -94,15 +95,21 @@
     public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
             TaskStackLayoutAlgorithm stackLayout) {
         if (mTaskIndexMap.containsKey(task.key)) {
-            // This is a freeform task, so lay it out in the freeform workspace
+            Rect taskRect = stackLayout.mTaskRect;
             int taskIndex = mTaskIndexMap.get(task.key);
-            int topOffset = (stackLayout.mFreeformRect.top - stackLayout.mTaskRect.top);
+            int topOffset = (stackLayout.mFreeformRect.top - taskRect.top);
             int x = taskIndex % mFreeformCellXCount;
             int y = taskIndex / mFreeformCellXCount;
-            float scale = (float) mFreeformCellWidth / stackLayout.mTaskRect.width();
-            int scaleXOffset = (int) (((1f - scale) * stackLayout.mTaskRect.width()) / 2);
-            int scaleYOffset = (int) (((1f - scale) * stackLayout.mTaskRect.height()) / 2);
-            transformOut.scale = scale * 0.9f;
+
+            int bitmapWidth = task.thumbnail.getWidth();
+            int bitmapHeight = task.thumbnail.getHeight();
+            float thumbnailScale = Math.min((float) mFreeformCellWidth / bitmapWidth,
+                    (float) mFreeformCellHeight / bitmapHeight);
+            float thumbnailWidth = bitmapWidth * thumbnailScale;
+            float thumbnailHeight = bitmapHeight * thumbnailScale;
+            int scaleXOffset = (int) (((1f - thumbnailScale) * thumbnailWidth) / 2);
+            int scaleYOffset = (int) (((1f - thumbnailScale) * thumbnailHeight) / 2);
+            transformOut.scale = thumbnailScale * 0.9f;
             transformOut.translationX = x * mFreeformCellWidth - scaleXOffset;
             transformOut.translationY = topOffset + y * mFreeformCellHeight - scaleYOffset;
             transformOut.translationZ = stackLayout.mMaxTranslationZ;
@@ -115,7 +122,6 @@
             if (DEBUG) {
                 Log.d(TAG, "getTransform: " + task.key + ", " + transformOut);
             }
-
             return transformOut;
         }
         return null;
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 0557f65..5616018 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -81,7 +81,6 @@
 
     RecentsTransitionHelper mTransitionHelper;
     RecentsViewTouchHandler mTouchHandler;
-    DragView mDragView;
     TaskStack.DockState[] mVisibleDockStates = {
             TaskStack.DockState.LEFT,
             TaskStack.DockState.TOP,
@@ -341,13 +340,6 @@
             mTaskStackView.measure(widthMeasureSpec, heightMeasureSpec);
         }
 
-        if (mDragView != null) {
-            Rect taskRect = mTaskStackView.mLayoutAlgorithm.mTaskRect;
-            mDragView.measure(
-                    MeasureSpec.makeMeasureSpec(taskRect.width(), MeasureSpec.AT_MOST),
-                    MeasureSpec.makeMeasureSpec(taskRect.height(), MeasureSpec.AT_MOST));
-        }
-
         // Measure the history button with the full space above the stack, but width-constrained
         // to the stack
         Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
@@ -379,11 +371,6 @@
             mTaskStackView.layout(left, top, left + getMeasuredWidth(), top + getMeasuredHeight());
         }
 
-        if (mDragView != null) {
-            mDragView.layout(left, top, left + mDragView.getMeasuredWidth(),
-                    top + mDragView.getMeasuredHeight());
-        }
-
         // Layout the history button left-aligned with the stack, but offset from the top of the
         // view
         Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
@@ -461,10 +448,6 @@
     /**** EventBus Events ****/
 
     public final void onBusEvent(DragStartEvent event) {
-        // Add the drag view
-        mDragView = event.dragView;
-        addView(mDragView);
-
         updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
                 TaskStack.DockState.NONE.viewState.dockAreaAlpha);
     }
@@ -480,65 +463,17 @@
     }
 
     public final void onBusEvent(final DragEndEvent event) {
-        final Runnable cleanUpRunnable = new Runnable() {
-            @Override
-            public void run() {
-                // Remove the drag view
-                removeView(mDragView);
-                mDragView = null;
-            }
-        };
-
         // Animate the overlay alpha back to 0
         updateVisibleDockRegions(null, -1);
 
-        if (event.dropTarget == null) {
-            // No drop targets for hit, so just animate the task back to its place
-            event.postAnimationTrigger.increment();
-            event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
-                @Override
-                public void run() {
-                    cleanUpRunnable.run();
-                }
-            });
-            // Animate the task back to where it was before then clean up afterwards
-            TaskViewTransform taskTransform = new TaskViewTransform();
-            TaskStackLayoutAlgorithm layoutAlgorithm = mTaskStackView.getStackAlgorithm();
-            layoutAlgorithm.getStackTransform(event.task,
-                    mTaskStackView.getScroller().getStackScroll(), taskTransform, null);
-            event.dragView.animate()
-                    .scaleX(taskTransform.scale)
-                    .scaleY(taskTransform.scale)
-                    .translationX((layoutAlgorithm.mTaskRect.left - event.dragView.getLeft())
-                            + taskTransform.translationX)
-                    .translationY((layoutAlgorithm.mTaskRect.top - event.dragView.getTop())
-                            + taskTransform.translationY)
-                    .setDuration(175)
-                    .setInterpolator(mFastOutSlowInInterpolator)
-                    .withEndAction(event.postAnimationTrigger.decrementAsRunnable())
-                    .start();
-
-        } else if (event.dropTarget instanceof TaskStack.DockState) {
+        // Handle the case where we drop onto a dock region
+        if (event.dropTarget instanceof TaskStack.DockState) {
             final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
 
-            // For now, just remove the drag view and the original task
-            // TODO: Animate the task to the drop target rect before launching it above
-            cleanUpRunnable.run();
-
             // Dock the task and launch it
             SystemServicesProxy ssp = Recents.getSystemServices();
             ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode);
             launchTask(event.task, null, INVALID_STACK_ID);
-
-        } else {
-            // We dropped on another drop target, so just add the cleanup to the post animation
-            // trigger
-            event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
-                @Override
-                public void run() {
-                    cleanUpRunnable.run();
-                }
-            });
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index c7edc92..c55f383 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -64,8 +64,8 @@
 
     private Task mDragTask;
     private TaskView mTaskView;
-    private DragView mDragView;
 
+    private Point mTaskViewOffset = new Point();
     private Point mDownPos = new Point();
     private boolean mDragging;
 
@@ -115,13 +115,16 @@
         mDragging = true;
         mDragTask = event.task;
         mTaskView = event.taskView;
-        mDragView = event.dragView;
         mDropTargets.clear();
 
-        float x = mDownPos.x - mDragView.getTopLeftOffset().x;
-        float y = mDownPos.y - mDragView.getTopLeftOffset().y;
-        mDragView.setTranslationX(x);
-        mDragView.setTranslationY(y);
+        int[] recentsViewLocation = new int[2];
+        mRv.getLocationInWindow(recentsViewLocation);
+        mTaskViewOffset.set(mTaskView.getLeft() - recentsViewLocation[0] + event.tlOffset.x,
+                mTaskView.getTop() - recentsViewLocation[1] + event.tlOffset.y);
+        float x = mDownPos.x - mTaskViewOffset.x;
+        float y = mDownPos.y - mTaskViewOffset.y;
+        mTaskView.setTranslationX(x);
+        mTaskView.setTranslationY(y);
 
         RecentsConfiguration config = Recents.getConfiguration();
         if (!config.hasDockedTasks) {
@@ -140,7 +143,6 @@
         mDragging = false;
         mDragTask = null;
         mTaskView = null;
-        mDragView = null;
         mLastDropTarget = null;
     }
 
@@ -160,8 +162,8 @@
                     int height = mRv.getMeasuredHeight();
                     float evX = ev.getX();
                     float evY = ev.getY();
-                    float x = evX - mDragView.getTopLeftOffset().x;
-                    float y = evY - mDragView.getTopLeftOffset().y;
+                    float x = evX - mTaskViewOffset.x;
+                    float y = evY - mTaskViewOffset.y;
 
                     DropTarget currentDropTarget = null;
                     for (DropTarget target : mDropTargets) {
@@ -176,8 +178,8 @@
                                 currentDropTarget));
                     }
 
-                    mDragView.setTranslationX(x);
-                    mDragView.setTranslationY(y);
+                    mTaskView.setTranslationX(x);
+                    mTaskView.setTranslationY(y);
                 }
                 break;
             }
@@ -187,7 +189,7 @@
                     ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger(
                             mRv.getContext(), null, null, null);
                     postAnimationTrigger.increment();
-                    EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView, mDragView,
+                    EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
                             mLastDropTarget, postAnimationTrigger));
                     postAnimationTrigger.decrement();
                     break;
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 30efd5f..c02eaf8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1420,7 +1424,12 @@
         }
     }
 
+    private AnimatorSet mDropAnimation;
+
     public final void onBusEvent(DragStartEvent event) {
+        // Cancel the existing drop animation
+        Utilities.cancelAnimationWithoutCallbacks(mDropAnimation);
+
         if (event.task.isFreeformTask()) {
             // Animate to the front of the stack
             mStackScroller.animateScroll(mStackScroller.getStackScroll(),
@@ -1441,56 +1450,84 @@
     }
 
     public final void onBusEvent(final DragEndEvent event) {
-        if (event.dropTarget != mFreeformWorkspaceDropTarget &&
-                event.dropTarget != mStackDropTarget) {
-            return;
-        }
-        if (event.task.isFreeformTask() && event.dropTarget == mFreeformWorkspaceDropTarget) {
-            // TODO: Animate back into view
-            return;
-        }
-        if (!event.task.isFreeformTask() && event.dropTarget == mStackDropTarget) {
-            // TODO: Animate back into view
+        // We don't handle drops on the dock regions
+        if (event.dropTarget instanceof TaskStack.DockState) {
             return;
         }
 
-        // Move the task to the right position in the stack (ie. the front of the stack if freeform
-        // or the front of the stack if fullscreen).  Note, we MUST move the tasks before we update
-        // their stack ids, otherwise, the keys will have changed.
-        if (event.dropTarget == mFreeformWorkspaceDropTarget) {
-            mStack.moveTaskToStack(event.task, FREEFORM_WORKSPACE_STACK_ID);
-            updateLayout(true);
-        } else if (event.dropTarget == mStackDropTarget) {
-            mStack.moveTaskToStack(event.task, FULLSCREEN_WORKSPACE_STACK_ID);
-            updateLayout(true);
+        boolean isFreeformTask = event.task.isFreeformTask();
+        boolean hasChangedStacks =
+                (!isFreeformTask && event.dropTarget == mFreeformWorkspaceDropTarget) ||
+                        (isFreeformTask && event.dropTarget == mStackDropTarget);
+        if (hasChangedStacks) {
+            ArrayList<Animator> animations = new ArrayList<>();
+
+            // Move the task to the right position in the stack (ie. the front of the stack if
+            // freeform or the front of the stack if fullscreen).  Note, we MUST move the tasks
+            // before we update their stack ids, otherwise, the keys will have changed.
+            if (event.dropTarget == mFreeformWorkspaceDropTarget) {
+                mStack.moveTaskToStack(event.task, FREEFORM_WORKSPACE_STACK_ID);
+                updateLayout(true);
+
+                // Update the clipping to match the scaled bitmap rect
+                TaskViewThumbnail thumbnailView = event.taskView.mThumbnailView;
+                float thumbnailScale = thumbnailView.computeThumbnailScale(true);
+                RectF bitmapRect = thumbnailView.getScaledBitmapRect(thumbnailScale);
+                AnimateableViewBounds viewBounds = event.taskView.getViewBounds();
+                int clipRight = (int) (thumbnailView.getMeasuredWidth() - bitmapRect.width());
+                int clipBottom = (int) (thumbnailView.getMeasuredHeight() - bitmapRect.height());
+                animations.add(ObjectAnimator.ofFloat(thumbnailView, TaskViewThumbnail.BITMAP_SCALE,
+                        thumbnailView.getBitmapScale(), thumbnailScale));
+                animations.add(ObjectAnimator.ofInt(viewBounds, AnimateableViewBounds.CLIP_BOTTOM,
+                        viewBounds.getClipBottom(), clipBottom));
+                animations.add(ObjectAnimator.ofInt(viewBounds, AnimateableViewBounds.CLIP_RIGHT,
+                        viewBounds.getClipRight(), clipRight));
+            } else if (event.dropTarget == mStackDropTarget) {
+                mStack.moveTaskToStack(event.task, FULLSCREEN_WORKSPACE_STACK_ID);
+                updateLayout(true);
+
+                // Reset the clipping when animating to the stack
+                TaskViewThumbnail thumbnailView = event.taskView.mThumbnailView;
+                float thumbnailScale = thumbnailView.computeThumbnailScale(false);
+                AnimateableViewBounds viewBounds = event.taskView.getViewBounds();
+                animations.add(ObjectAnimator.ofFloat(thumbnailView, TaskViewThumbnail.BITMAP_SCALE,
+                        thumbnailView.getBitmapScale(), thumbnailScale));
+                animations.add(ObjectAnimator.ofInt(viewBounds, AnimateableViewBounds.CLIP_BOTTOM,
+                        viewBounds.getClipBottom(), 0));
+                animations.add(ObjectAnimator.ofInt(viewBounds, AnimateableViewBounds.CLIP_RIGHT,
+                        viewBounds.getClipRight(), 0));
+            }
+
+            // Move the task to the new stack in the system after the animation completes
+            event.postAnimationTrigger.increment();
+            event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+                @Override
+                public void run() {
+                    SystemServicesProxy ssp = Recents.getSystemServices();
+                    ssp.moveTaskToStack(event.task.key.id, event.task.key.stackId);
+                }
+            });
+
+            // Animate the normal properties of the view
+            mDropAnimation = new AnimatorSet();
+            mDropAnimation.playTogether(animations);
+            mDropAnimation.setDuration(250);
+            mDropAnimation.setInterpolator(mFastOutSlowInInterpolator);
+            mDropAnimation.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    event.postAnimationTrigger.decrement();
+                }
+            });
+            mDropAnimation.start();
         }
 
         event.postAnimationTrigger.increment();
-        event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
-            @Override
-            public void run() {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                ssp.moveTaskToStack(event.task.key.id, event.task.key.stackId);
-            }
-        });
+        event.taskView.animate()
+                .withEndAction(event.postAnimationTrigger.decrementAsRunnable());
 
-        // Animate the drag view to the new position
-        mLayoutAlgorithm.getStackTransform(event.task, mStackScroller.getStackScroll(),
-                mTmpTransform, null);
-        event.dragView.animate()
-                .scaleX(mTmpTransform.scale)
-                .scaleY(mTmpTransform.scale)
-                .translationX((mLayoutAlgorithm.mTaskRect.left - event.dragView.getLeft())
-                        + mTmpTransform.translationX)
-                .translationY((mLayoutAlgorithm.mTaskRect.top - event.dragView.getTop())
-                        + mTmpTransform.translationY)
-                .setDuration(175)
-                .setInterpolator(mFastOutSlowInInterpolator)
-                .withEndAction(event.postAnimationTrigger.decrementAsRunnable())
-                .start();
-
-        // Animate the other views into place
-        requestSynchronizeStackViewsWithModel(175);
+        // Animate the tack view back into position
+        requestSynchronizeStackViewsWithModel(250);
     }
 
     public final void onBusEvent(StackViewScrolledEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 6db2eb9..fb84a22 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -22,8 +22,6 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Outline;
 import android.graphics.Paint;
@@ -244,6 +242,8 @@
     void resetViewProperties() {
         setDim(0);
         setLayerType(View.LAYER_TYPE_NONE, null);
+        setVisibility(View.VISIBLE);
+        getViewBounds().reset();
         TaskViewTransform.reset(this);
         if (mActionButtonView != null) {
             mActionButtonView.setScaleX(1f);
@@ -251,18 +251,6 @@
             mActionButtonView.setAlpha(1f);
             mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
         }
-        setVisibility(View.VISIBLE);
-    }
-
-    /**
-     * When we are un/filtering, this method will set up the transform that we are animating to,
-     * in order to hide the task.
-     */
-    void prepareTaskTransformForFilterTaskHidden(TaskViewTransform toTransform) {
-        // Fade the view out and slide it away
-        toTransform.alpha = 0f;
-        toTransform.translationY += 200;
-        toTransform.translationZ = 0;
     }
 
     /** Prepares this task view for the enter-recents animations.  This is called earlier in the
@@ -296,8 +284,6 @@
         }
         // Apply the current dim
         setDim(initialDim);
-        // Prepare the thumbnail view alpha
-        mThumbnailView.prepareEnterRecentsAnimation(isTaskViewLaunchTargetTask);
     }
 
     /** Animates this task view as it enters recents */
@@ -425,9 +411,6 @@
                 R.dimen.recents_task_view_affiliate_group_enter_offset);
 
         if (isLaunchingTask) {
-            // Animate the thumbnail alpha back into full opacity for the window animation out
-            mThumbnailView.startLaunchTaskAnimation(postAnimRunnable);
-
             // Animate the dim
             if (mDimAlpha > 0) {
                 ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", 0);
@@ -637,7 +620,6 @@
         mIsFocused = isFocused;
         mIsFocusAnimated = animated;
         mHeaderView.onTaskViewFocusChanged(isFocused, animated);
-        mThumbnailView.onFocusChanged(isFocused);
         if (isFocused) {
             if (requestViewFocus && !isFocused()) {
                 requestFocus();
@@ -746,54 +728,20 @@
             // Start listening for drag events
             setClipViewInStack(false);
 
+            // Enlarge the view slightly
             final float finalScale = getScaleX() * 1.05f;
-            final int width = getWidth();
-            final int height = getHeight();
-            Bitmap dragBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-            Canvas c = new Canvas(dragBitmap);
-            mThumbnailView.draw(c);
-            mHeaderView.draw(c);
-            c.setBitmap(null);
+            animate()
+                    .scaleX(finalScale)
+                    .scaleY(finalScale)
+                    .setDuration(175)
+                    .setInterpolator(mFastOutSlowInInterpolator)
+                    .start();
 
-            // The downTouchPos is relative to the currently transformed TaskView, but we will be
-            // dragging a copy of the full task view, which makes it easier for us to animate them
-            // when the user drops
-            mDownTouchPos.x += ((1f - getScaleX()) * width) / 2;
-            mDownTouchPos.y += ((1f - getScaleY()) * height) / 2;
+            mDownTouchPos.x += ((1f - getScaleX()) * getWidth()) / 2;
+            mDownTouchPos.y += ((1f - getScaleY()) * getHeight()) / 2;
 
-            // Initiate the drag
-            final DragView dragView = new DragView(getContext(), dragBitmap, mDownTouchPos);
-            dragView.setOutlineProvider(new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    outline.setRect(0, 0, width, height);
-                }
-            });
-            dragView.setScaleX(getScaleX());
-            dragView.setScaleY(getScaleY());
-            dragView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
-                @Override
-                public void onViewAttachedToWindow(View v) {
-                    // Hide this task view after the drag view is attached
-                    setVisibility(View.INVISIBLE);
-                    // Animate the alpha slightly to indicate dragging
-                    dragView.setElevation(getElevation());
-                    dragView.setTranslationZ(getTranslationZ());
-                    dragView.animate()
-                            .scaleX(finalScale)
-                            .scaleY(finalScale)
-                            .setDuration(175)
-                            .setInterpolator(mFastOutSlowInInterpolator)
-                            .start();
-                }
-
-                @Override
-                public void onViewDetachedFromWindow(View v) {
-                    // Do nothing
-                }
-            });
             EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-            EventBus.getDefault().send(new DragStartEvent(mTask, this, dragView));
+            EventBus.getDefault().send(new DragStartEvent(mTask, this, mDownTouchPos));
             return true;
         }
         return false;
@@ -806,9 +754,6 @@
             event.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
                 @Override
                 public void run() {
-                    // Show this task view
-                    setVisibility(View.VISIBLE);
-
                     // Animate the drag view back from where it is, to the view location, then after
                     // it returns, update the clip state
                     setClipViewInStack(true);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index b3d263e..c288afb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
@@ -31,11 +28,12 @@
 import android.graphics.RectF;
 import android.graphics.Shader;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.util.Property;
 import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import com.android.systemui.R;
-import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 
 
@@ -45,6 +43,19 @@
  */
 public class TaskViewThumbnail extends View {
 
+    public static final Property<TaskViewThumbnail, Float> BITMAP_SCALE =
+            new FloatProperty<TaskViewThumbnail>("bitmapScale") {
+                @Override
+                public void setValue(TaskViewThumbnail object, float scale) {
+                    object.setBitmapScale(scale);
+                }
+
+                @Override
+                public Float get(TaskViewThumbnail object) {
+                    return object.getBitmapScale();
+                }
+            };
+
     private Task mTask;
 
     // Drawing
@@ -60,18 +71,6 @@
 
     Interpolator mFastOutSlowInInterpolator;
 
-    // Thumbnail alpha
-    float mThumbnailAlpha;
-    ValueAnimator mThumbnailAlphaAnimator;
-    ValueAnimator.AnimatorUpdateListener mThumbnailAlphaUpdateListener
-            = new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mThumbnailAlpha = (float) animation.getAnimatedValue();
-            updateThumbnailPaintFilter();
-        }
-    };
-
     // Task bar clipping, the top of this thumbnail can be clipped against the opaque header
     // bar that overlaps this thumbnail
     View mTaskBar;
@@ -105,17 +104,11 @@
     }
 
     @Override
-    protected void onFinishInflate() {
-        mThumbnailAlpha = getResources().getFloat(R.dimen.recents_task_view_thumbnail_alpha);
-        updateThumbnailPaintFilter();
-    }
-
-    @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         if (changed) {
             mLayoutRect.set(0, 0, getWidth(), getHeight());
-            updateThumbnailScale();
+            setBitmapScale(computeThumbnailScale(mTask != null ? mTask.isFreeformTask() : false));
         }
     }
 
@@ -137,12 +130,15 @@
                     Shader.TileMode.CLAMP);
             mDrawPaint.setShader(mBitmapShader);
             mBitmapRect.set(0, 0, bm.getWidth(), bm.getHeight());
-            updateThumbnailScale();
         } else {
             mBitmapShader = null;
             mDrawPaint.setShader(null);
         }
-        updateThumbnailPaintFilter();
+        if (mTask != null) {
+            setBitmapScale(computeThumbnailScale(mTask != null ? mTask.isFreeformTask() : false));
+        } else {
+            setBitmapScale(1f);
+        }
     }
 
     /** Updates the paint to draw the thumbnail. */
@@ -150,36 +146,61 @@
         if (mInvisible) {
             return;
         }
-        int mul = (int) ((1.0f - mDimAlpha) * mThumbnailAlpha * 255);
-        int add = (int) ((1.0f - mDimAlpha) * (1 - mThumbnailAlpha) * 255);
+        int mul = (int) ((1.0f - mDimAlpha) * 255);
         if (mBitmapShader != null) {
             mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul));
-            mLightingColorFilter.setColorAdd(Color.argb(0, add, add, add));
             mDrawPaint.setColorFilter(mLightingColorFilter);
             mDrawPaint.setColor(0xffffffff);
         } else {
-            int grey = mul + add;
+            int grey = mul;
             mDrawPaint.setColorFilter(null);
             mDrawPaint.setColor(Color.argb(255, grey, grey, grey));
         }
         invalidate();
     }
 
-    /** Updates the thumbnail shader's scale transform. */
-    void updateThumbnailScale() {
-        if (mBitmapShader != null) {
-            if (mTask.isFreeformTask()) {
-                // For freeform tasks, we scale the bitmap rect to fit in the layout rect
-                mBitmapScale = Math.min(mLayoutRect.width() / mBitmapRect.width(),
-                        mLayoutRect.height() / mBitmapRect.height());
-            } else {
-                // For stack tasks, we scale the bitmap to fit the width
-                mBitmapScale = Math.max(1f, mLayoutRect.width() / mBitmapRect.width());
-            }
+    /**
+     * Returns the scale to apply to a thumbnail bitmap relative to this view rect.
+     */
+    public float computeThumbnailScale(boolean isFreeformTask) {
+        if (isFreeformTask) {
+            // For freeform tasks, we scale the bitmap rect to fit in the layout rect
+            return Math.min(mLayoutRect.width() / mBitmapRect.width(),
+                    mLayoutRect.height() / mBitmapRect.height());
+        } else {
+            // For stack tasks, we scale the bitmap to fit the width
+            return Math.max(1f, mLayoutRect.width() / mBitmapRect.width());
+        }
+    }
 
+    /**
+     * Returns the scaled bitmap rect.
+     */
+    public RectF getScaledBitmapRect(float scale) {
+        RectF scaledBitmapRect = new RectF(mBitmapRect);
+        scaledBitmapRect.left *= scale;
+        scaledBitmapRect.top *= scale;
+        scaledBitmapRect.right *= scale;
+        scaledBitmapRect.bottom *= scale;
+        return scaledBitmapRect;
+    }
+
+    /**
+     * Sets the scale of the bitmap relative to this view.
+     */
+    public void setBitmapScale(float scale) {
+        if (mBitmapShader != null) {
+            mBitmapScale = scale;
             mScaleMatrix.setScale(mBitmapScale, mBitmapScale);
             mBitmapShader.setLocalMatrix(mScaleMatrix);
         }
+        if (!mInvisible) {
+            invalidate();
+        }
+    }
+
+    public float getBitmapScale() {
+        return mBitmapScale;
     }
 
     /** Updates the clip rect based on the given task bar. */
@@ -227,67 +248,4 @@
         mTask = null;
         setThumbnail(null);
     }
-
-    /** Handles focus changes. */
-    void onFocusChanged(boolean focused) {
-        if (focused) {
-            if (Float.compare(getAlpha(), 1f) != 0) {
-                startFadeAnimation(1f, 150, null);
-            }
-        } else {
-            float taskViewThumbnailAlpha = getResources().getFloat(
-                    R.dimen.recents_task_view_thumbnail_alpha);
-            if (Float.compare(getAlpha(), taskViewThumbnailAlpha) != 0) {
-                startFadeAnimation(taskViewThumbnailAlpha, 150, null);
-            }
-        }
-    }
-
-    /**
-     * Prepares for the enter recents animation, this gets called before the the view
-     * is first visible and will be followed by a startEnterRecentsAnimation() call.
-     */
-    void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask) {
-        if (isTaskViewLaunchTargetTask) {
-            mThumbnailAlpha = 1f;
-        } else {
-            mThumbnailAlpha = getResources().getFloat(
-                    R.dimen.recents_task_view_thumbnail_alpha);
-        }
-        updateThumbnailPaintFilter();
-    }
-
-    /** Animates this task thumbnail as it enters Recents. */
-    void startEnterRecentsAnimation(Runnable postAnimRunnable) {
-        float taskViewThumbnailAlpha = getResources().getFloat(
-                R.dimen.recents_task_view_thumbnail_alpha);
-        startFadeAnimation(taskViewThumbnailAlpha,
-                getResources().getInteger(R.integer.recents_task_enter_from_app_duration),
-                postAnimRunnable);
-    }
-
-    /** Animates this task thumbnail as it exits Recents. */
-    void startLaunchTaskAnimation(Runnable postAnimRunnable) {
-        int taskViewExitToAppDuration = mContext.getResources().getInteger(
-                R.integer.recents_task_exit_to_app_duration);
-        startFadeAnimation(1f, taskViewExitToAppDuration, postAnimRunnable);
-    }
-
-    /** Starts a new thumbnail alpha animation. */
-    void startFadeAnimation(float finalAlpha, int duration, final Runnable postAnimRunnable) {
-        Utilities.cancelAnimationWithoutCallbacks(mThumbnailAlphaAnimator);
-        mThumbnailAlphaAnimator = ValueAnimator.ofFloat(mThumbnailAlpha, finalAlpha);
-        mThumbnailAlphaAnimator.setDuration(duration);
-        mThumbnailAlphaAnimator.setInterpolator(mFastOutSlowInInterpolator);
-        mThumbnailAlphaAnimator.addUpdateListener(mThumbnailAlphaUpdateListener);
-        if (postAnimRunnable != null) {
-            mThumbnailAlphaAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    postAnimRunnable.run();
-                }
-            });
-        }
-        mThumbnailAlphaAnimator.start();
-    }
 }
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 e1aec6f..cddb1fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -143,7 +143,7 @@
     private final OnClickListener mImeSwitcherClickListener = new OnClickListener() {
         @Override
         public void onClick(View view) {
-            ((InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE))
+            mContext.getSystemService(InputMethodManager.class)
                     .showInputMethodPicker(true /* showAuxiliarySubtypes */);
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 93a8fd8..0917528 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -110,7 +110,7 @@
         // When enabling location, a user consent dialog will pop up, and the
         // setting won't be fully enabled until the user accepts the agreement.
         int mode = enabled
-                ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY : Settings.Secure.LOCATION_MODE_OFF;
+                ? Settings.Secure.LOCATION_MODE_PREVIOUS : Settings.Secure.LOCATION_MODE_OFF;
         // QuickSettings always runs as the owner, so specifically set the settings
         // for the current foreground user.
         return Settings.Secure
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 3d358ec..11fdbb5 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -433,7 +433,6 @@
                         AccessibilityEvent.obtain(event)).sendToTarget();
             }
             event.recycle();
-            getUserStateLocked(resolvedUserId).mHandledFeedbackTypes = 0;
         }
         return (OWN_PROCESS_ID != Binder.getCallingPid());
     }
@@ -1051,9 +1050,7 @@
                 Service service = state.mBoundServices.get(i);
 
                 if (service.mIsDefault == isDefault) {
-                    if (canDispatchEventToServiceLocked(service, event,
-                            state.mHandledFeedbackTypes)) {
-                        state.mHandledFeedbackTypes |= service.mFeedbackType;
+                    if (canDispatchEventToServiceLocked(service, event)) {
                         service.notifyAccessibilityEvent(event);
                     }
                 }
@@ -1088,19 +1085,14 @@
 
     /**
      * Determines if given event can be dispatched to a service based on the package of the
-     * event source and already notified services for that event type. Specifically, a
-     * service is notified if it is interested in events from the package and no other service
-     * providing the same feedback type has been notified. Exception are services the
-     * provide generic feedback (feedback type left as a safety net for unforeseen feedback
-     * types) which are always notified.
+     * event source. Specifically, a service is notified if it is interested in events from the
+     * package.
      *
      * @param service The potential receiver.
      * @param event The event.
-     * @param handledFeedbackTypes The feedback types for which services have been notified.
      * @return True if the listener should be notified, false otherwise.
      */
-    private boolean canDispatchEventToServiceLocked(Service service, AccessibilityEvent event,
-            int handledFeedbackTypes) {
+    private boolean canDispatchEventToServiceLocked(Service service, AccessibilityEvent event) {
 
         if (!service.canReceiveEventsLocked()) {
             return false;
@@ -1121,15 +1113,7 @@
         String packageName = (event.getPackageName() != null)
                 ? event.getPackageName().toString() : null;
 
-        if (packageNames.isEmpty() || packageNames.contains(packageName)) {
-            int feedbackType = service.mFeedbackType;
-            if ((handledFeedbackTypes & feedbackType) != feedbackType
-                    || feedbackType == AccessibilityServiceInfo.FEEDBACK_GENERIC) {
-                return true;
-            }
-        }
-
-        return false;
+        return (packageNames.isEmpty() || packageNames.contains(packageName));
     }
 
     private void unbindAllServicesLocked(UserState userState) {
@@ -3886,8 +3870,6 @@
         public final Set<ComponentName> mTouchExplorationGrantedServices =
                 new HashSet<>();
 
-        public int mHandledFeedbackTypes = 0;
-
         public int mLastSentClientState = -1;
 
         public boolean mIsAccessibilityEnabled;
@@ -3950,7 +3932,6 @@
             mBindingServices.clear();
 
             // Clear event management state.
-            mHandledFeedbackTypes = 0;
             mLastSentClientState = -1;
 
             // Clear state persisted in settings.
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index fc3a322..fcd56eb7 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -446,8 +446,7 @@
             String candidateLocale = null;
             if (hashCode == 0) {
                 // Spell checker language settings == "auto"
-                final InputMethodManager imm =
-                        (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
+                final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
                 if (imm != null) {
                     final InputMethodSubtype currentInputMethodSubtype =
                             imm.getCurrentInputMethodSubtype();
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 9eb66dd..2924cef 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -223,7 +223,7 @@
     }
 
     public void systemReady() {
-        mIm = (InputManager)mContext.getSystemService(Context.INPUT_SERVICE);
+        mIm = mContext.getSystemService(InputManager.class);
         mSettingObserver = new SettingsObserver(mH);
 
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 6687412..3b43633 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -33,7 +33,9 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
+import android.net.NetworkRequest;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
 import android.os.Binder;
@@ -213,6 +215,7 @@
         checkDunRequired();
     }
 
+    @Override
     public void interfaceStatusChanged(String iface, boolean up) {
         if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
         boolean found = false;
@@ -248,6 +251,7 @@
         }
     }
 
+    @Override
     public void interfaceLinkStateChanged(String iface, boolean up) {
         if (VDBG) Log.d(TAG, "interfaceLinkStateChanged " + iface + ", " + up);
         interfaceStatusChanged(iface, up);
@@ -280,6 +284,7 @@
         }
     }
 
+    @Override
     public void interfaceAdded(String iface) {
         if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
         boolean found = false;
@@ -311,6 +316,7 @@
         }
     }
 
+    @Override
     public void interfaceRemoved(String iface) {
         if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
         synchronized (mPublicSync) {
@@ -638,7 +644,7 @@
         return values;
     }
 
-    public void checkDunRequired() {
+    private void checkDunRequired() {
         int secureSetting = 2;
         TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
         if (tm != null) {
@@ -1135,10 +1141,8 @@
         static final int CMD_TETHER_MODE_UNREQUESTED = 2;
         // upstream connection change - do the right thing
         static final int CMD_UPSTREAM_CHANGED        = 3;
-        // we received notice that the cellular DUN connection is up
-        static final int CMD_CELL_CONNECTION_RENEW   = 4;
         // we don't have a valid upstream conn, check again after a delay
-        static final int CMD_RETRY_UPSTREAM          = 5;
+        static final int CMD_RETRY_UPSTREAM          = 4;
 
         // This indicates what a timeout event relates to.  A state that
         // sends itself a delayed timeout event and handles incoming timeout events
@@ -1157,13 +1161,12 @@
 
         private ArrayList<TetherInterfaceSM> mNotifyList;
 
-        private int mCurrentConnectionSequence;
         private int mMobileApnReserved = ConnectivityManager.TYPE_NONE;
+        private ConnectivityManager.NetworkCallback mMobileUpstreamCallback;
 
         private String mUpstreamIfaceName = null;
 
         private static final int UPSTREAM_SETTLE_TIME_MS     = 10000;
-        private static final int CELL_CONNECTION_RENEW_MS    = 40000;
 
         TetherMasterSM(String name, Looper looper) {
             super(name, looper);
@@ -1190,58 +1193,69 @@
         }
 
         class TetherMasterUtilState extends State {
-            protected final static boolean TRY_TO_SETUP_MOBILE_CONNECTION = true;
             protected final static boolean WAIT_FOR_NETWORK_TO_SETTLE     = false;
 
             @Override
             public boolean processMessage(Message m) {
                 return false;
             }
-            protected String enableString(int apnType) {
-                switch (apnType) {
-                case ConnectivityManager.TYPE_MOBILE_DUN:
-                    return Phone.FEATURE_ENABLE_DUN_ALWAYS;
-                case ConnectivityManager.TYPE_MOBILE:
-                case ConnectivityManager.TYPE_MOBILE_HIPRI:
-                    return Phone.FEATURE_ENABLE_HIPRI;
-                }
-                return null;
-            }
+
             protected boolean turnOnUpstreamMobileConnection(int apnType) {
-                boolean retValue = true;
-                if (apnType == ConnectivityManager.TYPE_NONE) return false;
-                if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection();
-                int result = PhoneConstants.APN_REQUEST_FAILED;
-                String enableString = enableString(apnType);
-                if (enableString == null) return false;
-                result = getConnectivityManager().startUsingNetworkFeature(
-                        ConnectivityManager.TYPE_MOBILE, enableString);
-                switch (result) {
-                case PhoneConstants.APN_ALREADY_ACTIVE:
-                case PhoneConstants.APN_REQUEST_STARTED:
-                    mMobileApnReserved = apnType;
-                    Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW);
-                    m.arg1 = ++mCurrentConnectionSequence;
-                    sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS);
-                    break;
-                case PhoneConstants.APN_REQUEST_FAILED:
-                default:
-                    retValue = false;
-                    break;
+                if (apnType == ConnectivityManager.TYPE_NONE) { return false; }
+
+                if (apnType != mMobileApnReserved) {
+                    // Unregister any previous mobile upstream callback because
+                    // this request, if any, will be different.
+                    turnOffUpstreamMobileConnection();
                 }
 
-                return retValue;
-            }
-            protected boolean turnOffUpstreamMobileConnection() {
-                // ignore pending renewal requests
-                ++mCurrentConnectionSequence;
-                if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) {
-                    getConnectivityManager().stopUsingNetworkFeature(
-                            ConnectivityManager.TYPE_MOBILE, enableString(mMobileApnReserved));
-                    mMobileApnReserved = ConnectivityManager.TYPE_NONE;
+                if (mMobileUpstreamCallback != null) {
+                    // Looks like we already filed a request for this apnType.
+                    return true;
                 }
+
+                switch (apnType) {
+                    case ConnectivityManager.TYPE_MOBILE_DUN:
+                    case ConnectivityManager.TYPE_MOBILE:
+                    case ConnectivityManager.TYPE_MOBILE_HIPRI:
+                        mMobileApnReserved = apnType;
+                        break;
+                    default:
+                        return false;
+                }
+
+                NetworkRequest.Builder builder = new NetworkRequest.Builder()
+                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+                if (apnType == ConnectivityManager.TYPE_MOBILE_DUN) {
+                    builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
+                           .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+                } else {
+                    builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+                }
+                NetworkRequest mobileUpstreamRequest = builder.build();
+                // Other mechanisms notice network and interface changes and act upon them.
+                // TODO, imminently: replace with a proper NetworkCallback-based scheme.
+                //
+                // TODO: Change the timeout from 0 (no onUnavailable callback) to use some
+                // moderate callback time (once timeout callbacks are implemented). This might
+                // be useful for updating some UI. Additionally, we should definitely log a
+                // message to aid in any subsequent debugging.
+                mMobileUpstreamCallback = new ConnectivityManager.NetworkCallback();
+                if (DBG) Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);
+                getConnectivityManager().requestNetwork(
+                        mobileUpstreamRequest, mMobileUpstreamCallback, 0, apnType);
+
                 return true;
             }
+
+            protected void turnOffUpstreamMobileConnection() {
+                if (mMobileUpstreamCallback != null) {
+                    getConnectivityManager().unregisterNetworkCallback(mMobileUpstreamCallback);
+                    mMobileUpstreamCallback = null;
+                }
+                mMobileApnReserved = ConnectivityManager.TYPE_NONE;
+            }
+
             protected boolean turnOnMasterTetherSettings() {
                 try {
                     mNMService.setIpForwardingEnabled(true);
@@ -1304,35 +1318,39 @@
                 }
 
                 if (DBG) {
-                    Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn ="
-                            + mPreferredUpstreamMobileApn + ", got type=" + upType);
+                    Log.d(TAG, "chooseUpstreamType(" + tryCell + "),"
+                            + " preferredApn="
+                            + ConnectivityManager.getNetworkTypeName(mPreferredUpstreamMobileApn)
+                            + ", got type="
+                            + ConnectivityManager.getNetworkTypeName(upType));
                 }
 
-                // if we're on DUN, put our own grab on it
-                if (upType == ConnectivityManager.TYPE_MOBILE_DUN ||
-                        upType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
-                    turnOnUpstreamMobileConnection(upType);
-                } else if (upType != ConnectivityManager.TYPE_NONE) {
-                    /* If we've found an active upstream connection that's not DUN/HIPRI
-                     * we should stop any outstanding DUN/HIPRI start requests.
-                     *
-                     * If we found NONE we don't want to do this as we want any previous
-                     * requests to keep trying to bring up something we can use.
-                     */
-                    turnOffUpstreamMobileConnection();
+                switch (upType) {
+                    case ConnectivityManager.TYPE_MOBILE_DUN:
+                    case ConnectivityManager.TYPE_MOBILE_HIPRI:
+                        // If we're on DUN, put our own grab on it.
+                        turnOnUpstreamMobileConnection(upType);
+                        break;
+                    case ConnectivityManager.TYPE_NONE:
+                        if (tryCell &&
+                                turnOnUpstreamMobileConnection(mPreferredUpstreamMobileApn)) {
+                            // We think mobile should be coming up; don't set a retry.
+                        } else {
+                            sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
+                        }
+                        break;
+                    default:
+                        /* If we've found an active upstream connection that's not DUN/HIPRI
+                         * we should stop any outstanding DUN/HIPRI start requests.
+                         *
+                         * If we found NONE we don't want to do this as we want any previous
+                         * requests to keep trying to bring up something we can use.
+                         */
+                        turnOffUpstreamMobileConnection();
+                        break;
                 }
 
-                if (upType == ConnectivityManager.TYPE_NONE) {
-                    boolean tryAgainLater = true;
-                    if ((tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) &&
-                            (turnOnUpstreamMobileConnection(mPreferredUpstreamMobileApn) == true)) {
-                        // we think mobile should be coming up - don't set a retry
-                        tryAgainLater = false;
-                    }
-                    if (tryAgainLater) {
-                        sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
-                    }
-                } else {
+                if (upType != ConnectivityManager.TYPE_NONE) {
                     LinkProperties linkProperties =
                             getConnectivityManager().getLinkProperties(upType);
                     if (linkProperties != null) {
@@ -1579,17 +1597,6 @@
                         chooseUpstreamType(mTryCell);
                         mTryCell = !mTryCell;
                         break;
-                    case CMD_CELL_CONNECTION_RENEW:
-                        // make sure we're still using a requested connection - may have found
-                        // wifi or something since then.
-                        if (mCurrentConnectionSequence == message.arg1) {
-                            if (VDBG) {
-                                Log.d(TAG, "renewing mobile connection - requeuing for another " +
-                                        CELL_CONNECTION_RENEW_MS + "ms");
-                            }
-                            turnOnUpstreamMobileConnection(mMobileApnReserved);
-                        }
-                        break;
                     case CMD_RETRY_UPSTREAM:
                         chooseUpstreamType(mTryCell);
                         mTryCell = !mTryCell;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 946fbb1..38893b8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1286,10 +1286,11 @@
                     Binder.getCallingUid(), incomingUserId, true, false,
                     "getAppActiveNotifications", pkg);
 
-            final int N = mNotificationList.size();
-            final ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>(N);
+            final ArrayList<StatusBarNotification> list
+                    = new ArrayList<StatusBarNotification>(mNotificationList.size());
 
             synchronized (mNotificationList) {
+                final int N = mNotificationList.size();
                 for (int i = 0; i < N; i++) {
                     final StatusBarNotification sbn = mNotificationList.get(i).sbn;
                     if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId) {
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index b32ec2d..4861acc 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -109,7 +109,7 @@
     public AppWindowAnimator(final AppWindowToken atoken) {
         mAppToken = atoken;
         mService = atoken.service;
-        mAnimator = atoken.mAnimator;
+        mAnimator = mService.mAnimator;
     }
 
     public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 425ff9b..77a29f3 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -24,6 +24,7 @@
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.wm.WindowManagerService.H;
 
+import android.annotation.NonNull;
 import android.content.pm.ActivityInfo;
 import android.os.Message;
 import android.os.RemoteException;
@@ -49,9 +50,7 @@
     // All of the windows and child windows that are included in this
     // application token.  Note this list is NOT sorted!
     final WindowList allAppWindows = new WindowList();
-    final AppWindowAnimator mAppAnimator;
-
-    final WindowAnimator mAnimator;
+    @NonNull final AppWindowAnimator mAppAnimator;
 
     final boolean voiceInteraction;
 
@@ -145,7 +144,6 @@
         appToken = _token;
         voiceInteraction = _voiceInteraction;
         mInputApplicationHandle = new InputApplicationHandle(this);
-        mAnimator = service.mAnimator;
         mAppAnimator = new AppWindowAnimator(this);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 46fab2a..f20c4e5 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -220,8 +220,8 @@
 
         if (appShowWhenLocked != null) {
             allowWhenLocked |= appShowWhenLocked == win.mAppToken
-                    // Show all SHOW_WHEN_LOCKED windows while they're animating
-                    || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.isAnimatingLw()
+                    // Show all SHOW_WHEN_LOCKED windows if some apps are shown over lockscreen
+                    || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
                     // Show error dialogs over apps that dismiss keyguard.
                     || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
         }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8199250..d7afdf4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5567,8 +5567,8 @@
             // InputMethodManager fetches input methods for current user.
             // So this can only be set when calling user is the current user
             // or parent is current user in case of managed profiles.
-            InputMethodManager inputMethodManager = (InputMethodManager) mContext
-                    .getSystemService(Context.INPUT_METHOD_SERVICE);
+            InputMethodManager inputMethodManager =
+                    mContext.getSystemService(InputMethodManager.class);
             List<InputMethodInfo> enabledImes = inputMethodManager.getEnabledInputMethodList();
 
             if (enabledImes != null) {
@@ -5646,8 +5646,8 @@
 
             // If we have a permitted list add all system input methods.
             if (result != null) {
-                InputMethodManager inputMethodManager = (InputMethodManager) mContext
-                        .getSystemService(Context.INPUT_METHOD_SERVICE);
+                InputMethodManager inputMethodManager =
+                        mContext.getSystemService(InputMethodManager.class);
                 List<InputMethodInfo> imes = inputMethodManager.getInputMethodList();
                 long id = mInjector.binderClearCallingIdentity();
                 try {
@@ -6823,6 +6823,9 @@
     public boolean isProvisioningAllowed(String action) {
         final int callingUserId = mInjector.userHandleGetCallingUserId();
         if (DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE.equals(action)) {
+            if (!hasFeatureManagedUsers()) {
+                return false;
+            }
             synchronized (this) {
                 if (mOwners.hasDeviceOwner()) {
                     if (!mInjector.userManagerIsSplitSystemUser()) {
@@ -6845,13 +6848,6 @@
                 // Managed user cannot have a managed profile.
                 return false;
             }
-            try {
-                if (!mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
-                    return false;
-                }
-            } catch (RemoteException e) {
-                return false;
-            }
             final long ident = mInjector.binderClearCallingIdentity();
             try {
                 if (!mUserManager.canAddMoreManagedProfiles(callingUserId, true)) {
@@ -6864,10 +6860,17 @@
         } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE.equals(action)) {
             return isDeviceOwnerProvisioningAllowed(callingUserId);
         } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_USER.equals(action)) {
+            if (!hasFeatureManagedUsers()) {
+                return false;
+            }
             if (!mInjector.userManagerIsSplitSystemUser()) {
                 // ACTION_PROVISION_MANAGED_USER only supported on split-user systems.
                 return false;
             }
+            if (callingUserId == UserHandle.USER_SYSTEM) {
+                // System user cannot be a managed user.
+                return false;
+            }
             if (hasUserSetupCompleted(callingUserId)) {
                 return false;
             }
@@ -6901,6 +6904,14 @@
         return true;
     }
 
+    private boolean hasFeatureManagedUsers() {
+        try {
+            return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     @Override
     public String getWifiMacAddress() {
         // Make sure caller has DO.
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 97e16da..27deb72 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -591,6 +591,12 @@
     public void setUp() throws Exception {
         super.setUp();
 
+        // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
+        // http://b/25897652 .
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
         mServiceContext = new MockContext(getContext());
         mService = new WrappedConnectivityService(mServiceContext,
                 mock(INetworkManagementService.class),
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 4115756..17bd08c 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1805,6 +1805,13 @@
     public void onReject(String replyMessage) {}
 
     /**
+     * Notifies the Connection of a request to silence the ringer.
+     *
+     * @hide
+     */
+    public void onSilence() {}
+
+    /**
      * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
      */
     public void onPostDialContinue(boolean proceed) {}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 6223495..b4a7ce0 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -102,6 +102,7 @@
     private static final int MSG_MERGE_CONFERENCE = 18;
     private static final int MSG_SWAP_CONFERENCE = 19;
     private static final int MSG_REJECT_WITH_MESSAGE = 20;
+    private static final int MSG_SILENCE = 21;
 
     private static Connection sNullConnection;
 
@@ -177,6 +178,11 @@
         }
 
         @Override
+        public void silence(String callId) {
+            mHandler.obtainMessage(MSG_SILENCE, callId).sendToTarget();
+        }
+
+        @Override
         public void disconnect(String callId) {
             mHandler.obtainMessage(MSG_DISCONNECT, callId).sendToTarget();
         }
@@ -319,6 +325,9 @@
                 case MSG_DISCONNECT:
                     disconnect((String) msg.obj);
                     break;
+                case MSG_SILENCE:
+                    silence((String) msg.obj);
+                    break;
                 case MSG_HOLD:
                     hold((String) msg.obj);
                     break;
@@ -708,6 +717,11 @@
         findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
     }
 
+    private void silence(String callId) {
+        Log.d(this, "silence %s", callId);
+        findConnectionForAction(callId, "silence").onSilence();
+    }
+
     private void disconnect(String callId) {
         Log.d(this, "disconnect %s", callId);
         if (mConnectionById.containsKey(callId)) {
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index dd253cf..8a54add 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -54,6 +54,8 @@
 
     void disconnect(String callId);
 
+    void silence(String callId);
+
     void hold(String callId);
 
     void unhold(String callId);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index e22e76d..fb0fe38 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1537,12 +1537,20 @@
     std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();
     while (!workQueue.empty()) {
         CompileResourceWorkItem& workItem = workQueue.front();
-        err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file, &table, xmlFlags);
+        int xmlCompilationFlags = xmlFlags | XML_COMPILE_PARSE_VALUES
+                | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS;
+        if (!workItem.needsCompiling) {
+            xmlCompilationFlags &= ~XML_COMPILE_ASSIGN_ATTRIBUTE_IDS;
+            xmlCompilationFlags &= ~XML_COMPILE_PARSE_VALUES;
+        }
+        err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.xmlRoot,
+                             workItem.file, &table, xmlCompilationFlags);
+
         if (err == NO_ERROR) {
             assets->addResource(workItem.resPath.getPathLeaf(),
-                    workItem.resPath,
-                    workItem.file,
-                    workItem.file->getResourceType());
+                                workItem.resPath,
+                                workItem.file,
+                                workItem.file->getResourceType());
         } else {
             hasErrors = true;
         }
@@ -1737,9 +1745,7 @@
             manifestFile->getGroupEntry(),
             manifestFile->getResourceType());
     err = compileXmlFile(bundle, assets, String16(), manifestFile,
-            outManifestFile, &table,
-            XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
-            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES);
+            outManifestFile, &table, XML_COMPILE_STANDARD_RESOURCE & ~XML_COMPILE_STRIP_COMMENTS);
     if (err < NO_ERROR) {
         return err;
     }
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index d5a09d8..0e470d9 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -88,8 +88,11 @@
         root->setUTF8(true);
     }
 
-    bool hasErrors = false;
+    if (table->processBundleFormat(bundle, resourceName, target, root) != NO_ERROR) {
+        return UNKNOWN_ERROR;
+    }
     
+    bool hasErrors = false;
     if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
         status_t err = root->assignResourceIds(assets, table);
         if (err != NO_ERROR) {
@@ -97,9 +100,11 @@
         }
     }
 
-    status_t err = root->parseValues(assets, table);
-    if (err != NO_ERROR) {
-        hasErrors = true;
+    if ((options&XML_COMPILE_PARSE_VALUES) != 0) {
+        status_t err = root->parseValues(assets, table);
+        if (err != NO_ERROR) {
+            hasErrors = true;
+        }
     }
 
     if (hasErrors) {
@@ -114,7 +119,7 @@
         printf("Input XML Resource:\n");
         root->print();
     }
-    err = root->flatten(target,
+    status_t err = root->flatten(target,
             (options&XML_COMPILE_STRIP_COMMENTS) != 0,
             (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
     if (err != NO_ERROR) {
@@ -4755,9 +4760,9 @@
         newConfig.sdkVersion = sdkVersionToGenerate;
         sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
                 AaptGroupEntry(newConfig), target->getResourceType());
-        String8 resPath = String8::format("res/%s/%s",
+        String8 resPath = String8::format("res/%s/%s.xml",
                 newFile->getGroupEntry().toDirName(target->getResourceType()).string(),
-                target->getSourceFile().getPathLeaf().string());
+                String8(resourceName).string());
         resPath.convertToResPath();
 
         // Add a resource table entry.
@@ -4784,9 +4789,11 @@
         item.resourceName = resourceName;
         item.resPath = resPath;
         item.file = newFile;
+        item.xmlRoot = newRoot;
+        item.needsCompiling = false;    // This step occurs after we parse/assign, so we don't need
+                                        // to do it again.
         mWorkQueue.push(item);
     }
-
     return NO_ERROR;
 }
 
@@ -4825,3 +4832,226 @@
         }
     }
 }
+
+static String16 buildNamespace(const String16& package) {
+    return String16("http://schemas.android.com/apk/res/") + package;
+}
+
+static sp<XMLNode> findOnlyChildElement(const sp<XMLNode>& parent) {
+    const Vector<sp<XMLNode> >& children = parent->getChildren();
+    sp<XMLNode> onlyChild;
+    for (size_t i = 0; i < children.size(); i++) {
+        if (children[i]->getType() != XMLNode::TYPE_CDATA) {
+            if (onlyChild != NULL) {
+                return NULL;
+            }
+            onlyChild = children[i];
+        }
+    }
+    return onlyChild;
+}
+
+/**
+ * Detects use of the `bundle' format and extracts nested resources into their own top level
+ * resources. The bundle format looks like this:
+ *
+ * <!-- res/drawable/bundle.xml -->
+ * <animated-vector xmlns:aapt="http://schemas.android.com/aapt">
+ *   <aapt:attr name="android:drawable">
+ *     <vector android:width="60dp"
+ *             android:height="60dp">
+ *       <path android:name="v"
+ *             android:fillColor="#000000"
+ *             android:pathData="M300,70 l 0,-70 70,..." />
+ *     </vector>
+ *   </aapt:attr>
+ * </animated-vector>
+ *
+ * When AAPT sees the <aapt:attr> tag, it will extract its single element and its children
+ * into a new high-level resource, assigning it a name and ID. Then value of the `name`
+ * attribute must be a resource attribute. That resource attribute is inserted into the parent
+ * with the reference to the extracted resource as the value.
+ *
+ * <!-- res/drawable/bundle.xml -->
+ * <animated-vector android:drawable="@drawable/bundle_1.xml">
+ * </animated-vector>
+ *
+ * <!-- res/drawable/bundle_1.xml -->
+ * <vector android:width="60dp"
+ *         android:height="60dp">
+ *   <path android:name="v"
+ *         android:fillColor="#000000"
+ *         android:pathData="M300,70 l 0,-70 70,..." />
+ * </vector>
+ */
+status_t ResourceTable::processBundleFormat(const Bundle* bundle,
+                                            const String16& resourceName,
+                                            const sp<AaptFile>& target,
+                                            const sp<XMLNode>& root) {
+    Vector<sp<XMLNode> > namespaces;
+    if (root->getType() == XMLNode::TYPE_NAMESPACE) {
+        namespaces.push(root);
+    }
+    return processBundleFormatImpl(bundle, resourceName, target, root, &namespaces);
+}
+
+status_t ResourceTable::processBundleFormatImpl(const Bundle* bundle,
+                                                const String16& resourceName,
+                                                const sp<AaptFile>& target,
+                                                const sp<XMLNode>& parent,
+                                                Vector<sp<XMLNode> >* namespaces) {
+    const String16 kAaptNamespaceUri16("http://schemas.android.com/aapt");
+    const String16 kName16("name");
+    const String16 kAttr16("attr");
+    const String16 kAssetPackage16(mAssets->getPackage());
+
+    Vector<sp<XMLNode> >& children = parent->getChildren();
+    for (size_t i = 0; i < children.size(); i++) {
+        const sp<XMLNode>& child = children[i];
+
+        if (child->getType() == XMLNode::TYPE_CDATA) {
+            continue;
+        } else if (child->getType() == XMLNode::TYPE_NAMESPACE) {
+            namespaces->push(child);
+        }
+
+        if (child->getElementNamespace() != kAaptNamespaceUri16 ||
+                child->getElementName() != kAttr16) {
+            status_t result = processBundleFormatImpl(bundle, resourceName, target, child,
+                                                      namespaces);
+            if (result != NO_ERROR) {
+                return result;
+            }
+
+            if (child->getType() == XMLNode::TYPE_NAMESPACE) {
+                namespaces->pop();
+            }
+            continue;
+        }
+
+        // This is the <aapt:attr> tag. Look for the 'name' attribute.
+        SourcePos source(child->getFilename(), child->getStartLineNumber());
+
+        sp<XMLNode> nestedRoot = findOnlyChildElement(child);
+        if (nestedRoot == NULL) {
+            source.error("<%s:%s> must have exactly one child element",
+                         String8(child->getElementNamespace()).string(),
+                         String8(child->getElementName()).string());
+            return UNKNOWN_ERROR;
+        }
+
+        // Find the special attribute 'parent-attr'. This attribute's value contains
+        // the resource attribute for which this element should be assigned in the parent.
+        const XMLNode::attribute_entry* attr = child->getAttribute(String16(), kName16);
+        if (attr == NULL) {
+            source.error("inline resource definition must specify an attribute via 'name'");
+            return UNKNOWN_ERROR;
+        }
+
+        // Parse the attribute name.
+        const char* errorMsg = NULL;
+        String16 attrPackage, attrType, attrName;
+        bool result = ResTable::expandResourceRef(attr->string.string(),
+                                                  attr->string.size(),
+                                                  &attrPackage, &attrType, &attrName,
+                                                  &kAttr16, &kAssetPackage16,
+                                                  &errorMsg, NULL);
+        if (!result) {
+            source.error("invalid attribute name for 'name': %s", errorMsg);
+            return UNKNOWN_ERROR;
+        }
+
+        if (attrType != kAttr16) {
+            // The value of the 'name' attribute must be an attribute reference.
+            source.error("value of 'name' must be an attribute reference.");
+            return UNKNOWN_ERROR;
+        }
+
+        // Generate a name for this nested resource and try to add it to the table.
+        // We do this in a loop because the name may be taken, in which case we will
+        // increment a suffix until we succeed.
+        String8 nestedResourceName;
+        String8 nestedResourcePath;
+        int suffix = 1;
+        while (true) {
+            // This child element will be extracted into its own resource file.
+            // Generate a name and path for it from its parent.
+            nestedResourceName = String8::format("%s_%d",
+                        String8(resourceName).string(), suffix++);
+            nestedResourcePath = String8::format("res/%s/%s.xml",
+                        target->getGroupEntry().toDirName(target->getResourceType())
+                                               .string(),
+                        nestedResourceName.string());
+
+            // Lookup or create the entry for this name.
+            sp<Entry> entry = getEntry(kAssetPackage16,
+                                       String16(target->getResourceType()),
+                                       String16(nestedResourceName),
+                                       source,
+                                       false,
+                                       &target->getGroupEntry().toParams(),
+                                       true);
+            if (entry == NULL) {
+                return UNKNOWN_ERROR;
+            }
+
+            if (entry->getType() == Entry::TYPE_UNKNOWN) {
+                // The value for this resource has never been set,
+                // meaning we're good!
+                entry->setItem(source, String16(nestedResourcePath));
+                break;
+            }
+
+            // We failed (name already exists), so try with a different name
+            // (increment the suffix).
+        }
+
+        if (bundle->getVerbose()) {
+            source.printf("generating nested resource %s:%s/%s",
+                    mAssets->getPackage().string(), target->getResourceType().string(),
+                    nestedResourceName.string());
+        }
+
+        // Build the attribute reference and assign it to the parent.
+        String16 nestedResourceRef = String16(String8::format("@%s:%s/%s",
+                    mAssets->getPackage().string(), target->getResourceType().string(),
+                    nestedResourceName.string()));
+
+        String16 attrNs = buildNamespace(attrPackage);
+        if (parent->getAttribute(attrNs, attrName) != NULL) {
+            SourcePos(parent->getFilename(), parent->getStartLineNumber())
+                    .error("parent of nested resource already defines attribute '%s:%s'",
+                           String8(attrPackage).string(), String8(attrName).string());
+            return UNKNOWN_ERROR;
+        }
+
+        // Add the reference to the inline resource.
+        parent->addAttribute(attrNs, attrName, nestedResourceRef);
+
+        // Remove the <aapt:attr> child element from here.
+        children.removeAt(i);
+        i--;
+
+        // Append all namespace declarations that we've seen on this branch in the XML tree
+        // to this resource.
+        // We do this because the order of namespace declarations and prefix usage is determined
+        // by the developer and we do not want to override any decisions. Be conservative.
+        for (size_t nsIndex = namespaces->size(); nsIndex > 0; nsIndex--) {
+            const sp<XMLNode>& ns = namespaces->itemAt(nsIndex - 1);
+            sp<XMLNode> newNs = XMLNode::newNamespace(ns->getFilename(), ns->getNamespacePrefix(),
+                                                      ns->getNamespaceUri());
+            newNs->addChild(nestedRoot);
+            nestedRoot = newNs;
+        }
+
+        // Schedule compilation of the nested resource.
+        CompileResourceWorkItem workItem;
+        workItem.resPath = nestedResourcePath;
+        workItem.resourceName = String16(nestedResourceName);
+        workItem.xmlRoot = nestedRoot;
+        workItem.file = new AaptFile(target->getSourceFile(), target->getGroupEntry(),
+                                     target->getResourceType());
+        mWorkQueue.push(workItem);
+    }
+    return NO_ERROR;
+}
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index c4bdf09..4b7b3cd 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -23,13 +23,14 @@
 enum {
     XML_COMPILE_STRIP_COMMENTS = 1<<0,
     XML_COMPILE_ASSIGN_ATTRIBUTE_IDS = 1<<1,
-    XML_COMPILE_COMPACT_WHITESPACE = 1<<2,
-    XML_COMPILE_STRIP_WHITESPACE = 1<<3,
-    XML_COMPILE_STRIP_RAW_VALUES = 1<<4,
-    XML_COMPILE_UTF8 = 1<<5,
+    XML_COMPILE_PARSE_VALUES = 1 << 2,
+    XML_COMPILE_COMPACT_WHITESPACE = 1<<3,
+    XML_COMPILE_STRIP_WHITESPACE = 1<<4,
+    XML_COMPILE_STRIP_RAW_VALUES = 1<<5,
+    XML_COMPILE_UTF8 = 1<<6,
 
     XML_COMPILE_STANDARD_RESOURCE =
-            XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
+            XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS | XML_COMPILE_PARSE_VALUES
             | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES
 };
 
@@ -83,6 +84,8 @@
     String16 resourceName;
     String8 resPath;
     sp<AaptFile> file;
+    sp<XMLNode> xmlRoot;
+    bool needsCompiling = true;
 };
 
 class ResourceTable : public ResTable::Accessor
@@ -206,6 +209,12 @@
                              const sp<AaptFile>& file,
                              const sp<XMLNode>& root);
 
+    status_t processBundleFormat(const Bundle* bundle,
+                                 const String16& resourceName,
+                                 const sp<AaptFile>& file,
+                                 const sp<XMLNode>& parent);
+
+
     sp<AaptFile> flatten(Bundle* bundle, const sp<const ResourceFilter>& filter,
             const bool isBase);
 
@@ -586,6 +595,11 @@
                       Res_value* outValue);
     int getPublicAttributeSdkLevel(uint32_t attrId) const;
 
+    status_t processBundleFormatImpl(const Bundle* bundle,
+                                     const String16& resourceName,
+                                     const sp<AaptFile>& file,
+                                     const sp<XMLNode>& parent,
+                                     Vector<sp<XMLNode> >* namespaces);
 
     String16 mAssetsPackage;
     PackageType mPackageType;
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index dc08eb8..5b215da 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -693,6 +693,12 @@
     return mChildren;
 }
 
+
+Vector<sp<XMLNode> >& XMLNode::getChildren()
+{
+    return mChildren;
+}
+
 const String8& XMLNode::getFilename() const
 {
     return mFilename;
@@ -717,6 +723,18 @@
     return NULL;
 }
 
+bool XMLNode::removeAttribute(const String16& ns, const String16& name)
+{
+    for (size_t i = 0; i < mAttributes.size(); i++) {
+        const attribute_entry& ae(mAttributes.itemAt(i));
+        if (ae.ns == ns && ae.name == name) {
+            removeAttribute(i);
+            return true;
+        }
+    }
+    return false;
+}
+
 XMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns,
         const String16& name)
 {
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
index b9e5cd5..749bf9f 100644
--- a/tools/aapt/XMLNode.h
+++ b/tools/aapt/XMLNode.h
@@ -55,7 +55,7 @@
     sp<XMLNode> newCData(const String8& filename) {
         return new XMLNode(filename);
     }
-    
+
     enum type {
         TYPE_NAMESPACE,
         TYPE_ELEMENT,
@@ -70,6 +70,7 @@
     const String16& getElementNamespace() const;
     const String16& getElementName() const;
     const Vector<sp<XMLNode> >& getChildren() const;
+    Vector<sp<XMLNode> >& getChildren();
 
     const String8& getFilename() const;
     
@@ -97,6 +98,7 @@
     const Vector<attribute_entry>& getAttributes() const;
 
     const attribute_entry* getAttribute(const String16& ns, const String16& name) const;
+    bool removeAttribute(const String16& ns, const String16& name);
     
     attribute_entry* editAttribute(const String16& ns, const String16& name);
 
diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp
index 17a658e..90e35d5 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -22,6 +22,7 @@
 #include "compile/IdAssigner.h"
 #include "compile/Png.h"
 #include "compile/XmlIdCollector.h"
+#include "flatten/Archive.h"
 #include "flatten/FileExportWriter.h"
 #include "flatten/TableFlattener.h"
 #include "flatten/XmlFlattener.h"
@@ -31,6 +32,7 @@
 #include "xml/XmlDom.h"
 #include "xml/XmlPullParser.h"
 
+#include <dirent.h>
 #include <fstream>
 #include <string>
 
@@ -90,7 +92,7 @@
     }
 
     return ResourcePathData{
-            Source{ path },
+            Source(path),
             util::utf8ToUtf16(dirStr),
             util::utf8ToUtf16(name),
             extension.toString(),
@@ -101,25 +103,79 @@
 
 struct CompileOptions {
     std::string outputPath;
+    Maybe<std::string> resDir;
     Maybe<std::u16string> product;
     bool verbose = false;
 };
 
-static std::string buildIntermediateFilename(const std::string outDir,
-                                             const ResourcePathData& data) {
+static std::string buildIntermediateFilename(const ResourcePathData& data) {
     std::stringstream name;
     name << data.resourceDir;
     if (!data.configStr.empty()) {
         name << "-" << data.configStr;
     }
     name << "_" << data.name << "." << data.extension << ".flat";
-    std::string outPath = outDir;
-    file::appendPath(&outPath, name.str());
-    return outPath;
+    return name.str();
+}
+
+static bool isHidden(const StringPiece& filename) {
+    return util::stringStartsWith<char>(filename, ".");
+}
+
+/**
+ * Walks the res directory structure, looking for resource files.
+ */
+static bool loadInputFilesFromDir(IAaptContext* context, const CompileOptions& options,
+                                  std::vector<ResourcePathData>* outPathData) {
+    const std::string& rootDir = options.resDir.value();
+    std::unique_ptr<DIR, decltype(closedir)*> d(opendir(rootDir.data()), closedir);
+    if (!d) {
+        context->getDiagnostics()->error(DiagMessage() << strerror(errno));
+        return false;
+    }
+
+    while (struct dirent* entry = readdir(d.get())) {
+        if (isHidden(entry->d_name)) {
+            continue;
+        }
+
+        std::string prefixPath = rootDir;
+        file::appendPath(&prefixPath, entry->d_name);
+
+        if (file::getFileType(prefixPath) != file::FileType::kDirectory) {
+            continue;
+        }
+
+        std::unique_ptr<DIR, decltype(closedir)*> subDir(opendir(prefixPath.data()), closedir);
+        if (!subDir) {
+            context->getDiagnostics()->error(DiagMessage() << strerror(errno));
+            return false;
+        }
+
+        while (struct dirent* leafEntry = readdir(subDir.get())) {
+            if (isHidden(leafEntry->d_name)) {
+                continue;
+            }
+
+            std::string fullPath = prefixPath;
+            file::appendPath(&fullPath, leafEntry->d_name);
+
+            std::string errStr;
+            Maybe<ResourcePathData> pathData = extractResourcePathData(fullPath, &errStr);
+            if (!pathData) {
+                context->getDiagnostics()->error(DiagMessage() << errStr);
+                return false;
+            }
+
+            outPathData->push_back(std::move(pathData.value()));
+        }
+    }
+    return true;
 }
 
 static bool compileTable(IAaptContext* context, const CompileOptions& options,
-                         const ResourcePathData& pathData, const std::string& outputPath) {
+                         const ResourcePathData& pathData, IArchiveWriter* writer,
+                         const std::string& outputPath) {
     ResourceTable table;
     {
         std::ifstream fin(pathData.source.path, std::ifstream::binary);
@@ -150,6 +206,7 @@
     // Ensure we have the compilation package at least.
     table.createPackage(context->getCompilationPackage());
 
+    // Assign an ID to any package that has resources.
     for (auto& pkg : table.packages) {
         if (!pkg->id) {
             // If no package ID was set while parsing (public identifiers), auto assign an ID.
@@ -172,23 +229,24 @@
         return false;
     }
 
-    // Build the output filename.
-    std::ofstream fout(outputPath, std::ofstream::binary);
-    if (!fout) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
+    if (!writer->startEntry(outputPath, 0)) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
         return false;
     }
 
-    // Write it to disk.
-    if (!util::writeAll(fout, buffer)) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
-        return false;
+    if (writer->writeEntry(buffer)) {
+        if (writer->finishEntry()) {
+            return true;
+        }
     }
-    return true;
+
+    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+    return false;
 }
 
 static bool compileXml(IAaptContext* context, const CompileOptions& options,
-                       const ResourcePathData& pathData, const std::string& outputPath) {
+                       const ResourcePathData& pathData, IArchiveWriter* writer,
+                       const std::string& outputPath) {
 
     std::unique_ptr<xml::XmlResource> xmlRes;
 
@@ -214,7 +272,7 @@
         return false;
     }
 
-    xmlRes->file.name = ResourceName{ {}, *parseResourceType(pathData.resourceDir), pathData.name };
+    xmlRes->file.name = ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
     xmlRes->file.config = pathData.config;
     xmlRes->file.source = pathData.source;
 
@@ -230,25 +288,27 @@
 
     fileExportWriter.finish();
 
-    std::ofstream fout(outputPath, std::ofstream::binary);
-    if (!fout) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
+    if (!writer->startEntry(outputPath, 0)) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
         return false;
     }
 
-    // Write it to disk.
-    if (!util::writeAll(fout, buffer)) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
-        return false;
+    if (writer->writeEntry(buffer)) {
+        if (writer->finishEntry()) {
+            return true;
+        }
     }
-    return true;
+
+    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+    return false;
 }
 
 static bool compilePng(IAaptContext* context, const CompileOptions& options,
-                       const ResourcePathData& pathData, const std::string& outputPath) {
+                       const ResourcePathData& pathData, IArchiveWriter* writer,
+                       const std::string& outputPath) {
     BigBuffer buffer(4096);
     ResourceFile resFile;
-    resFile.name = ResourceName{ {}, *parseResourceType(pathData.resourceDir), pathData.name };
+    resFile.name = ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
     resFile.config = pathData.config;
     resFile.source = pathData.source;
 
@@ -269,24 +329,27 @@
 
     fileExportWriter.finish();
 
-    std::ofstream fout(outputPath, std::ofstream::binary);
-    if (!fout) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
+    if (!writer->startEntry(outputPath, 0)) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
         return false;
     }
 
-    if (!util::writeAll(fout, buffer)) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
-        return false;
+    if (writer->writeEntry(buffer)) {
+        if (writer->finishEntry()) {
+            return true;
+        }
     }
-    return true;
+
+    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+    return false;
 }
 
 static bool compileFile(IAaptContext* context, const CompileOptions& options,
-                        const ResourcePathData& pathData, const std::string& outputPath) {
+                        const ResourcePathData& pathData, IArchiveWriter* writer,
+                        const std::string& outputPath) {
     BigBuffer buffer(256);
     ResourceFile resFile;
-    resFile.name = ResourceName{ {}, *parseResourceType(pathData.resourceDir), pathData.name };
+    resFile.name = ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
     resFile.config = pathData.config;
     resFile.source = pathData.source;
 
@@ -299,9 +362,8 @@
         return false;
     }
 
-    std::ofstream fout(outputPath, std::ofstream::binary);
-    if (!fout) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
+    if (!writer->startEntry(outputPath, 0)) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
         return false;
     }
 
@@ -309,16 +371,17 @@
     // the buffer the entire file.
     fileExportWriter.getChunkHeader()->size =
             util::hostToDevice32(buffer.size() + f.value().getDataLength());
-    if (!util::writeAll(fout, buffer)) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
-        return false;
+
+    if (writer->writeEntry(buffer)) {
+        if (writer->writeEntry(f.value().getDataPtr(), f.value().getDataLength())) {
+            if (writer->finishEntry()) {
+                return true;
+            }
+        }
     }
 
-    if (!fout.write((const char*) f.value().getDataPtr(), f.value().getDataLength())) {
-        context->getDiagnostics()->error(DiagMessage(Source{ outputPath }) << strerror(errno));
-        return false;
-    }
-    return true;
+    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+    return false;
 }
 
 class CompileContext : public IAaptContext {
@@ -359,6 +422,7 @@
     Flags flags = Flags()
             .requiredFlag("-o", "Output path", &options.outputPath)
             .optionalFlag("--product", "Product type to compile", &product)
+            .optionalFlag("--dir", "Directory to scan for resources", &options.resDir)
             .optionalSwitch("-v", "Enables verbose logging", &options.verbose);
     if (!flags.parse("aapt2 compile", args, &std::cerr)) {
         return 1;
@@ -369,19 +433,42 @@
     }
 
     CompileContext context;
+    std::unique_ptr<IArchiveWriter> archiveWriter;
 
     std::vector<ResourcePathData> inputData;
-    inputData.reserve(flags.getArgs().size());
-
-    // Collect data from the path for each input file.
-    for (const std::string& arg : flags.getArgs()) {
-        std::string errorStr;
-        if (Maybe<ResourcePathData> pathData = extractResourcePathData(arg, &errorStr)) {
-            inputData.push_back(std::move(pathData.value()));
-        } else {
-            context.getDiagnostics()->error(DiagMessage() << errorStr << " (" << arg << ")");
+    if (options.resDir) {
+        if (!flags.getArgs().empty()) {
+            // Can't have both files and a resource directory.
+            context.getDiagnostics()->error(DiagMessage() << "files given but --dir specified");
+            flags.usage("aapt2 compile", &std::cerr);
             return 1;
         }
+
+        if (!loadInputFilesFromDir(&context, options, &inputData)) {
+            return 1;
+        }
+
+        archiveWriter = createZipFileArchiveWriter(context.getDiagnostics(), options.outputPath);
+
+    } else {
+        inputData.reserve(flags.getArgs().size());
+
+        // Collect data from the path for each input file.
+        for (const std::string& arg : flags.getArgs()) {
+            std::string errorStr;
+            if (Maybe<ResourcePathData> pathData = extractResourcePathData(arg, &errorStr)) {
+                inputData.push_back(std::move(pathData.value()));
+            } else {
+                context.getDiagnostics()->error(DiagMessage() << errorStr << " (" << arg << ")");
+                return 1;
+            }
+        }
+
+        archiveWriter = createDirectoryArchiveWriter(context.getDiagnostics(), options.outputPath);
+    }
+
+    if (!archiveWriter) {
+        return false;
     }
 
     bool error = false;
@@ -394,32 +481,34 @@
             // Overwrite the extension.
             pathData.extension = "arsc";
 
-            const std::string outputFilename = buildIntermediateFilename(
-                    options.outputPath, pathData);
-            if (!compileTable(&context, options, pathData, outputFilename)) {
+            const std::string outputFilename = buildIntermediateFilename(pathData);
+            if (!compileTable(&context, options, pathData, archiveWriter.get(), outputFilename)) {
                 error = true;
             }
 
         } else {
-            const std::string outputFilename = buildIntermediateFilename(options.outputPath,
-                                                                         pathData);
+            const std::string outputFilename = buildIntermediateFilename(pathData);
             if (const ResourceType* type = parseResourceType(pathData.resourceDir)) {
                 if (*type != ResourceType::kRaw) {
                     if (pathData.extension == "xml") {
-                        if (!compileXml(&context, options, pathData, outputFilename)) {
+                        if (!compileXml(&context, options, pathData, archiveWriter.get(),
+                                        outputFilename)) {
                             error = true;
                         }
                     } else if (pathData.extension == "png" || pathData.extension == "9.png") {
-                        if (!compilePng(&context, options, pathData, outputFilename)) {
+                        if (!compilePng(&context, options, pathData, archiveWriter.get(),
+                                        outputFilename)) {
                             error = true;
                         }
                     } else {
-                        if (!compileFile(&context, options, pathData, outputFilename)) {
+                        if (!compileFile(&context, options, pathData, archiveWriter.get(),
+                                         outputFilename)) {
                             error = true;
                         }
                     }
                 } else {
-                    if (!compileFile(&context, options, pathData, outputFilename)) {
+                    if (!compileFile(&context, options, pathData, archiveWriter.get(),
+                                     outputFilename)) {
                         error = true;
                     }
                 }
diff --git a/tools/aapt2/flatten/Archive.cpp b/tools/aapt2/flatten/Archive.cpp
index 6db13b8..3a244c0 100644
--- a/tools/aapt2/flatten/Archive.cpp
+++ b/tools/aapt2/flatten/Archive.cpp
@@ -18,7 +18,7 @@
 #include "util/Files.h"
 #include "util/StringPiece.h"
 
-#include <fstream>
+#include <cstdio>
 #include <memory>
 #include <string>
 #include <vector>
@@ -30,70 +30,85 @@
 
 struct DirectoryWriter : public IArchiveWriter {
     std::string mOutDir;
-    std::vector<std::unique_ptr<ArchiveEntry>> mEntries;
+    std::unique_ptr<FILE, decltype(fclose)*> mFile = { nullptr, fclose };
 
-    explicit DirectoryWriter(const StringPiece& outDir) : mOutDir(outDir.toString()) {
+    bool open(IDiagnostics* diag, const StringPiece& outDir) {
+        mOutDir = outDir.toString();
+        file::FileType type = file::getFileType(mOutDir);
+        if (type == file::FileType::kNonexistant) {
+            diag->error(DiagMessage() << "directory " << mOutDir << " does not exist");
+            return false;
+        } else if (type != file::FileType::kDirectory) {
+            diag->error(DiagMessage() << mOutDir << " is not a directory");
+            return false;
+        }
+        return true;
     }
 
-    ArchiveEntry* writeEntry(const StringPiece& path, uint32_t flags,
-                             const BigBuffer& buffer) override {
+    bool startEntry(const StringPiece& path, uint32_t flags) override {
+        if (mFile) {
+            return false;
+        }
+
         std::string fullPath = mOutDir;
         file::appendPath(&fullPath, path);
         file::mkdirs(file::getStem(fullPath));
 
-        std::ofstream fout(fullPath, std::ofstream::binary);
-        if (!fout) {
-            return nullptr;
+        mFile = { fopen(fullPath.data(), "wb"), fclose };
+        if (!mFile) {
+            return false;
         }
-
-        if (!util::writeAll(fout, buffer)) {
-            return nullptr;
-        }
-
-        mEntries.push_back(util::make_unique<ArchiveEntry>(fullPath, flags, buffer.size()));
-        return mEntries.back().get();
+        return true;
     }
 
-    ArchiveEntry* writeEntry(const StringPiece& path, uint32_t flags, android::FileMap* fileMap,
-                             size_t offset, size_t len) override {
-        std::string fullPath = mOutDir;
-        file::appendPath(&fullPath, path);
-        file::mkdirs(file::getStem(fullPath));
-
-        std::ofstream fout(fullPath, std::ofstream::binary);
-        if (!fout) {
-            return nullptr;
+    bool writeEntry(const BigBuffer& buffer) override {
+        if (!mFile) {
+            return false;
         }
 
-        if (!fout.write((const char*) fileMap->getDataPtr() + offset, len)) {
-            return nullptr;
+        for (const BigBuffer::Block& b : buffer) {
+            if (fwrite(b.buffer.get(), 1, b.size, mFile.get()) != b.size) {
+                mFile.reset(nullptr);
+                return false;
+            }
         }
-
-        mEntries.push_back(util::make_unique<ArchiveEntry>(fullPath, flags, len));
-        return mEntries.back().get();
+        return true;
     }
 
-    virtual ~DirectoryWriter() {
+    bool writeEntry(const void* data, size_t len) override {
+        if (fwrite(data, 1, len, mFile.get()) != len) {
+            mFile.reset(nullptr);
+            return false;
+        }
+        return true;
+    }
 
+    bool finishEntry() override {
+        if (!mFile) {
+            return false;
+        }
+        mFile.reset(nullptr);
+        return true;
     }
 };
 
 struct ZipFileWriter : public IArchiveWriter {
-    FILE* mFile;
+    std::unique_ptr<FILE, decltype(fclose)*> mFile = { nullptr, fclose };
     std::unique_ptr<ZipWriter> mWriter;
-    std::vector<std::unique_ptr<ArchiveEntry>> mEntries;
 
-    explicit ZipFileWriter(const StringPiece& path) {
-        mFile = fopen(path.data(), "w+b");
-        if (mFile) {
-            mWriter = util::make_unique<ZipWriter>(mFile);
+    bool open(IDiagnostics* diag, const StringPiece& path) {
+        mFile = { fopen(path.data(), "w+b"), fclose };
+        if (!mFile) {
+            diag->error(DiagMessage() << "failed to open " << path << ": " << strerror(errno));
+            return false;
         }
+        mWriter = util::make_unique<ZipWriter>(mFile.get());
+        return true;
     }
 
-    ArchiveEntry* writeEntry(const StringPiece& path, uint32_t flags,
-                             const BigBuffer& buffer) override {
+    bool startEntry(const StringPiece& path, uint32_t flags) override {
         if (!mWriter) {
-            return nullptr;
+            return false;
         }
 
         size_t zipFlags = 0;
@@ -107,75 +122,63 @@
 
         int32_t result = mWriter->StartEntry(path.data(), zipFlags);
         if (result != 0) {
-            return nullptr;
+            return false;
         }
+        return true;
+    }
 
+    bool writeEntry(const void* data, size_t len) override {
+        int32_t result = mWriter->WriteBytes(data, len);
+        if (result != 0) {
+            return false;
+        }
+        return true;
+    }
+
+    bool writeEntry(const BigBuffer& buffer) override {
         for (const BigBuffer::Block& b : buffer) {
-            result = mWriter->WriteBytes(reinterpret_cast<const uint8_t*>(b.buffer.get()), b.size);
+            int32_t result = mWriter->WriteBytes(b.buffer.get(), b.size);
             if (result != 0) {
-                return nullptr;
+                return false;
             }
         }
-
-        result = mWriter->FinishEntry();
-        if (result != 0) {
-            return nullptr;
-        }
-
-        mEntries.push_back(util::make_unique<ArchiveEntry>(path.toString(), flags, buffer.size()));
-        return mEntries.back().get();
+        return true;
     }
 
-    ArchiveEntry* writeEntry(const StringPiece& path, uint32_t flags, android::FileMap* fileMap,
-                             size_t offset, size_t len) override {
-        if (!mWriter) {
-            return nullptr;
-        }
-
-        size_t zipFlags = 0;
-        if (flags & ArchiveEntry::kCompress) {
-            zipFlags |= ZipWriter::kCompress;
-        }
-
-        if (flags & ArchiveEntry::kAlign) {
-            zipFlags |= ZipWriter::kAlign32;
-        }
-
-        int32_t result = mWriter->StartEntry(path.data(), zipFlags);
+    bool finishEntry() override {
+        int32_t result = mWriter->FinishEntry();
         if (result != 0) {
-            return nullptr;
+            return false;
         }
-
-        result = mWriter->WriteBytes((const char*) fileMap->getDataPtr() + offset, len);
-        if (result != 0) {
-            return nullptr;
-        }
-
-        result = mWriter->FinishEntry();
-        if (result != 0) {
-            return nullptr;
-        }
-
-        mEntries.push_back(util::make_unique<ArchiveEntry>(path.toString(), flags, len));
-        return mEntries.back().get();
+        return true;
     }
 
     virtual ~ZipFileWriter() {
         if (mWriter) {
             mWriter->Finish();
-            fclose(mFile);
         }
     }
 };
 
 } // namespace
 
-std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(const StringPiece& path) {
-    return util::make_unique<DirectoryWriter>(path);
+std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(IDiagnostics* diag,
+                                                             const StringPiece& path) {
+
+    std::unique_ptr<DirectoryWriter> writer = util::make_unique<DirectoryWriter>();
+    if (!writer->open(diag, path)) {
+        return {};
+    }
+    return std::move(writer);
 }
 
-std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(const StringPiece& path) {
-    return util::make_unique<ZipFileWriter>(path);
+std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(IDiagnostics* diag,
+                                                           const StringPiece& path) {
+    std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>();
+    if (!writer->open(diag, path)) {
+        return {};
+    }
+    return std::move(writer);
 }
 
 } // namespace aapt
diff --git a/tools/aapt2/flatten/Archive.h b/tools/aapt2/flatten/Archive.h
index c4ddeb3..6da1d2a 100644
--- a/tools/aapt2/flatten/Archive.h
+++ b/tools/aapt2/flatten/Archive.h
@@ -17,6 +17,7 @@
 #ifndef AAPT_FLATTEN_ARCHIVE_H
 #define AAPT_FLATTEN_ARCHIVE_H
 
+#include "Diagnostics.h"
 #include "util/BigBuffer.h"
 #include "util/Files.h"
 #include "util/StringPiece.h"
@@ -42,15 +43,17 @@
 struct IArchiveWriter {
     virtual ~IArchiveWriter() = default;
 
-    virtual ArchiveEntry* writeEntry(const StringPiece& path, uint32_t flags,
-                                     const BigBuffer& buffer) = 0;
-    virtual ArchiveEntry* writeEntry(const StringPiece& path, uint32_t flags,
-                                     android::FileMap* fileMap, size_t offset, size_t len) = 0;
+    virtual bool startEntry(const StringPiece& path, uint32_t flags) = 0;
+    virtual bool writeEntry(const BigBuffer& buffer) = 0;
+    virtual bool writeEntry(const void* data, size_t len) = 0;
+    virtual bool finishEntry() = 0;
 };
 
-std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(const StringPiece& path);
+std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(IDiagnostics* diag,
+                                                             const StringPiece& path);
 
-std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(const StringPiece& path);
+std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter(IDiagnostics* diag,
+                                                           const StringPiece& path);
 
 } // namespace aapt
 
diff --git a/tools/aapt2/io/Data.h b/tools/aapt2/io/Data.h
new file mode 100644
index 0000000..9081c55
--- /dev/null
+++ b/tools/aapt2/io/Data.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT_IO_DATA_H
+#define AAPT_IO_DATA_H
+
+#include <utils/FileMap.h>
+
+#include <memory>
+
+namespace aapt {
+namespace io {
+
+/**
+ * Interface for a block of contiguous memory. An instance of this interface owns the data.
+ */
+class IData {
+public:
+    virtual ~IData() = default;
+
+    virtual const void* data() const = 0;
+    virtual size_t size() const = 0;
+};
+
+/**
+ * Implementation of IData that exposes a memory mapped file. The mmapped file is owned by this
+ * object.
+ */
+class MmappedData : public IData {
+public:
+    explicit MmappedData(android::FileMap&& map) : mMap(std::forward<android::FileMap>(map)) {
+    }
+
+    const void* data() const override {
+        return mMap.getDataPtr();
+    }
+
+    size_t size() const override {
+        return mMap.getDataLength();
+    }
+
+private:
+    android::FileMap mMap;
+};
+
+/**
+ * Implementation of IData that exposes a block of memory that was malloc'ed (new'ed). The
+ * memory is owned by this object.
+ */
+class MallocData : public IData {
+public:
+    MallocData(std::unique_ptr<const uint8_t[]> data, size_t size) :
+            mData(std::move(data)), mSize(size) {
+    }
+
+    const void* data() const override {
+        return mData.get();
+    }
+
+    size_t size() const override {
+        return mSize;
+    }
+
+private:
+    std::unique_ptr<const uint8_t[]> mData;
+    size_t mSize;
+};
+
+} // namespace io
+} // namespace aapt
+
+#endif /* AAPT_IO_DATA_H */
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
new file mode 100644
index 0000000..9fca398
--- /dev/null
+++ b/tools/aapt2/io/File.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT_IO_FILE_H
+#define AAPT_IO_FILE_H
+
+#include "Source.h"
+#include "io/Data.h"
+
+#include <memory>
+#include <vector>
+
+namespace aapt {
+namespace io {
+
+/**
+ * Interface for a file, which could be a real file on the file system, or a file inside
+ * a ZIP archive.
+ */
+class IFile {
+public:
+    virtual ~IFile() = default;
+
+    /**
+     * Open the file and return it as a block of contiguous memory. How this occurs is
+     * implementation dependent. For example, if this is a file on the file system, it may
+     * simply mmap the contents. If this file represents a compressed file in a ZIP archive,
+     * it may need to inflate it to memory, incurring a copy.
+     *
+     * Returns nullptr on failure.
+     */
+    virtual std::unique_ptr<IData> openAsData() = 0;
+
+    /**
+     * Returns the source of this file. This is for presentation to the user and may not be a
+     * valid file system path (for example, it may contain a '@' sign to separate the files within
+     * a ZIP archive from the path to the containing ZIP archive.
+     */
+    virtual const Source& getSource() const = 0;
+};
+
+/**
+ * Interface for a collection of files, all of which share a common source. That source may
+ * simply be the filesystem, or a ZIP archive.
+ */
+class IFileCollection {
+public:
+    virtual ~IFileCollection() = default;
+
+    using const_iterator = std::vector<std::unique_ptr<IFile>>::const_iterator;
+
+    virtual const_iterator begin() const = 0;
+    virtual const_iterator end() const = 0;
+};
+
+} // namespace io
+} // namespace aapt
+
+#endif /* AAPT_IO_FILE_H */
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
new file mode 100644
index 0000000..5dbefcc
--- /dev/null
+++ b/tools/aapt2/io/FileSystem.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT_IO_FILESYSTEM_H
+#define AAPT_IO_FILESYSTEM_H
+
+#include "io/File.h"
+#include "util/Files.h"
+
+namespace aapt {
+namespace io {
+
+/**
+ * A regular file from the file system. Uses mmap to open the data.
+ */
+class RegularFile : public IFile {
+public:
+    RegularFile(const Source& source) : mSource(source) {
+    }
+
+    std::unique_ptr<IData> openAsData() override {
+        android::FileMap map;
+        if (Maybe<android::FileMap> map = file::mmapPath(mSource.path, nullptr)) {
+            return util::make_unique<MmappedData>(std::move(map.value()));
+        }
+        return {};
+    }
+
+    const Source& getSource() const override {
+        return mSource;
+    }
+
+private:
+    Source mSource;
+};
+
+/**
+ * An IFileCollection representing the file system.
+ */
+class FileCollection : public IFileCollection {
+public:
+    /**
+     * Adds a file located at path. Returns the IFile representation of that file.
+     */
+    IFile* insertFile(const StringPiece& path) {
+        mFiles.push_back(util::make_unique<RegularFile>(Source(path)));
+        return mFiles.back().get();
+    }
+
+    const_iterator begin() const override {
+        return mFiles.begin();
+    }
+
+    const_iterator end() const override {
+        return mFiles.end();
+    }
+
+private:
+    std::vector<std::unique_ptr<IFile>> mFiles;
+};
+
+} // namespace io
+} // namespace aapt
+
+#endif // AAPT_IO_FILESYSTEM_H
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
new file mode 100644
index 0000000..98afc49
--- /dev/null
+++ b/tools/aapt2/io/ZipArchive.h
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT_IO_ZIPARCHIVE_H
+#define AAPT_IO_ZIPARCHIVE_H
+
+#include "io/File.h"
+#include "util/StringPiece.h"
+
+#include <utils/FileMap.h>
+#include <ziparchive/zip_archive.h>
+
+namespace aapt {
+namespace io {
+
+/**
+ * An IFile representing a file within a ZIP archive. If the file is compressed, it is uncompressed
+ * and copied into memory when opened. Otherwise it is mmapped from the ZIP archive.
+ */
+class ZipFile : public IFile {
+public:
+    ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source) :
+            mZipHandle(handle), mZipEntry(entry), mSource(source) {
+    }
+
+    std::unique_ptr<IData> openAsData() override {
+        if (mZipEntry.method == kCompressStored) {
+            int fd = GetFileDescriptor(mZipHandle);
+
+            android::FileMap fileMap;
+            bool result = fileMap.create(nullptr, fd, mZipEntry.offset,
+                                         mZipEntry.uncompressed_length, true);
+            if (!result) {
+                return {};
+            }
+            return util::make_unique<MmappedData>(std::move(fileMap));
+
+        } else {
+            std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(
+                    new uint8_t[mZipEntry.uncompressed_length]);
+            int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(),
+                                             static_cast<uint32_t>(mZipEntry.uncompressed_length));
+            if (result != 0) {
+                return {};
+            }
+            return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length);
+        }
+    }
+
+    const Source& getSource() const override {
+        return mSource;
+    }
+
+private:
+    ZipArchiveHandle mZipHandle;
+    ZipEntry mZipEntry;
+    Source mSource;
+};
+
+/**
+ * An IFileCollection that represents a ZIP archive and the entries within it.
+ */
+class ZipFileCollection : public IFileCollection {
+public:
+    static std::unique_ptr<ZipFileCollection> create(const StringPiece& path,
+                                                     std::string* outError) {
+        std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>(
+                new ZipFileCollection());
+
+        int32_t result = OpenArchive(path.data(), &collection->mHandle);
+        if (result != 0) {
+            if (outError) *outError = ErrorCodeString(result);
+            return {};
+        }
+
+        ZipString suffix(".flat");
+        void* cookie = nullptr;
+        result = StartIteration(collection->mHandle, &cookie, nullptr, &suffix);
+        if (result != 0) {
+            if (outError) *outError = ErrorCodeString(result);
+            return {};
+        }
+
+        using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
+        IterationEnder iterationEnder(cookie, EndIteration);
+
+        ZipString zipEntryName;
+        ZipEntry zipData;
+        while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) {
+            std::string nestedPath = path.toString();
+            nestedPath += "@" + std::string(reinterpret_cast<const char*>(zipEntryName.name),
+                                            zipEntryName.name_length);
+            collection->mFiles.push_back(util::make_unique<ZipFile>(collection->mHandle,
+                                                                    zipData,
+                                                                    Source(nestedPath)));
+        }
+
+        if (result != -1) {
+            if (outError) *outError = ErrorCodeString(result);
+            return {};
+        }
+        return collection;
+    }
+
+    const_iterator begin() const override {
+        return mFiles.begin();
+    }
+
+    const_iterator end() const override {
+        return mFiles.end();
+    }
+
+    ~ZipFileCollection() override {
+        if (mHandle) {
+            CloseArchive(mHandle);
+        }
+    }
+
+private:
+    ZipFileCollection() : mHandle(nullptr) {
+    }
+
+    ZipArchiveHandle mHandle;
+    std::vector<std::unique_ptr<IFile>> mFiles;
+};
+
+} // namespace io
+} // namespace aapt
+
+#endif /* AAPT_IO_ZIPARCHIVE_H */
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 9850ae5..33d9272 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -22,6 +22,8 @@
 #include "flatten/Archive.h"
 #include "flatten/TableFlattener.h"
 #include "flatten/XmlFlattener.h"
+#include "io/FileSystem.h"
+#include "io/ZipArchive.h"
 #include "java/JavaClassGenerator.h"
 #include "java/ManifestClassGenerator.h"
 #include "java/ProguardRules.h"
@@ -39,7 +41,6 @@
 
 #include <fstream>
 #include <sys/stat.h>
-#include <utils/FileMap.h>
 #include <vector>
 
 namespace aapt {
@@ -92,7 +93,15 @@
 class LinkCommand {
 public:
     LinkCommand(const LinkOptions& options) :
-            mOptions(options), mContext(), mFinalTable() {
+            mOptions(options), mContext(), mFinalTable(), mFileCollection(nullptr) {
+        std::unique_ptr<io::FileCollection> fileCollection =
+                util::make_unique<io::FileCollection>();
+
+        // Get a pointer to the FileCollection for convenience, but it will be owned by the vector.
+        mFileCollection = fileCollection.get();
+
+        // Move it to the collection.
+        mCollections.push_back(std::move(fileCollection));
     }
 
     std::string buildResourceFileName(const ResourceFile& resFile) {
@@ -136,20 +145,9 @@
         return builder.build();
     }
 
-    /**
-     * Loads the resource table (not inside an apk) at the given path.
-     */
-    std::unique_ptr<ResourceTable> loadTable(const std::string& input) {
-        std::string errorStr;
-        Maybe<android::FileMap> map = file::mmapPath(input, &errorStr);
-        if (!map) {
-            mContext.getDiagnostics()->error(DiagMessage(input) << errorStr);
-            return {};
-        }
-
+    std::unique_ptr<ResourceTable> loadTable(const Source& source, const void* data, size_t len) {
         std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
-        BinaryResourceParser parser(&mContext, table.get(), Source(input),
-                                    map.value().getDataPtr(), map.value().getDataLength());
+        BinaryResourceParser parser(&mContext, table.get(), source, data, len);
         if (!parser.parse()) {
             return {};
         }
@@ -159,90 +157,79 @@
     /**
      * Inflates an XML file from the source path.
      */
-    std::unique_ptr<xml::XmlResource> loadXml(const std::string& path) {
+    static std::unique_ptr<xml::XmlResource> loadXml(const std::string& path, IDiagnostics* diag) {
         std::ifstream fin(path, std::ifstream::binary);
         if (!fin) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << strerror(errno));
+            diag->error(DiagMessage(path) << strerror(errno));
             return {};
         }
 
-        return xml::inflate(&fin, mContext.getDiagnostics(), Source(path));
+        return xml::inflate(&fin, diag, Source(path));
     }
 
-    /**
-     * Inflates a binary XML file from the source path.
-     */
-    std::unique_ptr<xml::XmlResource> loadBinaryXmlSkipFileExport(const std::string& path) {
-        // Read header for symbol info and export info.
+    static std::unique_ptr<xml::XmlResource> loadBinaryXmlSkipFileExport(
+            const Source& source,
+            const void* data, size_t len,
+            IDiagnostics* diag) {
         std::string errorStr;
-        Maybe<android::FileMap> maybeF = file::mmapPath(path, &errorStr);
-        if (!maybeF) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << errorStr);
-            return {};
-        }
-
-        ssize_t offset = getWrappedDataOffset(maybeF.value().getDataPtr(),
-                                              maybeF.value().getDataLength(), &errorStr);
+        ssize_t offset = getWrappedDataOffset(data, len, &errorStr);
         if (offset < 0) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << errorStr);
+            diag->error(DiagMessage(source) << errorStr);
             return {};
         }
 
         std::unique_ptr<xml::XmlResource> xmlRes = xml::inflate(
-                (const uint8_t*) maybeF.value().getDataPtr() + (size_t) offset,
-                maybeF.value().getDataLength() - offset,
-                mContext.getDiagnostics(), Source(path));
+                reinterpret_cast<const uint8_t*>(data) + static_cast<size_t>(offset),
+                len - static_cast<size_t>(offset),
+                diag,
+                source);
         if (!xmlRes) {
             return {};
         }
         return xmlRes;
     }
 
-    Maybe<ResourceFile> loadFileExportHeader(const std::string& path) {
-        // Read header for symbol info and export info.
+    static std::unique_ptr<ResourceFile> loadFileExportHeader(const Source& source,
+                                                              const void* data, size_t len,
+                                                              IDiagnostics* diag) {
+        std::unique_ptr<ResourceFile> resFile = util::make_unique<ResourceFile>();
         std::string errorStr;
-        Maybe<android::FileMap> maybeF = file::mmapPath(path, &errorStr);
-        if (!maybeF) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << errorStr);
-            return {};
-        }
-
-        ResourceFile resFile;
-        ssize_t offset = unwrapFileExportHeader(maybeF.value().getDataPtr(),
-                                                maybeF.value().getDataLength(),
-                                                &resFile, &errorStr);
+        ssize_t offset = unwrapFileExportHeader(data, len, resFile.get(), &errorStr);
         if (offset < 0) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << errorStr);
+            diag->error(DiagMessage(source) << errorStr);
             return {};
         }
-        return std::move(resFile);
+        return resFile;
     }
 
-    bool copyFileToArchive(const std::string& path, const std::string& outPath, uint32_t flags,
+    bool copyFileToArchive(io::IFile* file, const std::string& outPath, uint32_t flags,
                            IArchiveWriter* writer) {
+        std::unique_ptr<io::IData> data = file->openAsData();
+        if (!data) {
+            mContext.getDiagnostics()->error(DiagMessage(file->getSource())
+                                             << "failed to open file");
+            return false;
+        }
+
         std::string errorStr;
-        Maybe<android::FileMap> maybeF = file::mmapPath(path, &errorStr);
-        if (!maybeF) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << errorStr);
-            return false;
-        }
-
-        ssize_t offset = getWrappedDataOffset(maybeF.value().getDataPtr(),
-                                              maybeF.value().getDataLength(),
-                                              &errorStr);
+        ssize_t offset = getWrappedDataOffset(data->data(), data->size(), &errorStr);
         if (offset < 0) {
-            mContext.getDiagnostics()->error(DiagMessage(path) << errorStr);
+            mContext.getDiagnostics()->error(DiagMessage(file->getSource()) << errorStr);
             return false;
         }
 
-        ArchiveEntry* entry = writer->writeEntry(outPath, flags, &maybeF.value(),
-                                                 offset, maybeF.value().getDataLength() - offset);
-        if (!entry) {
-            mContext.getDiagnostics()->error(
-                    DiagMessage(mOptions.outputPath) << "failed to write file " << outPath);
-            return false;
+        if (writer->startEntry(outPath, flags)) {
+            if (writer->writeEntry(reinterpret_cast<const uint8_t*>(data->data()) + offset,
+                                   data->size() - static_cast<size_t>(offset))) {
+                if (writer->finishEntry()) {
+                    return true;
+                }
+            }
         }
-        return true;
+
+        mContext.getDiagnostics()->error(
+                DiagMessage(mOptions.outputPath) << "failed to write file " << outPath);
+        return false;
     }
 
     Maybe<AppInfo> extractAppInfoFromManifest(xml::XmlResource* xmlRes) {
@@ -285,9 +272,9 @@
 
     std::unique_ptr<IArchiveWriter> makeArchiveWriter() {
         if (mOptions.outputToDirectory) {
-            return createDirectoryArchiveWriter(mOptions.outputPath);
+            return createDirectoryArchiveWriter(mContext.getDiagnostics(), mOptions.outputPath);
         } else {
-            return createZipFileArchiveWriter(mOptions.outputPath);
+            return createZipFileArchiveWriter(mContext.getDiagnostics(), mOptions.outputPath);
         }
     }
 
@@ -300,13 +287,17 @@
             return false;
         }
 
-        ArchiveEntry* entry = writer->writeEntry("resources.arsc", ArchiveEntry::kAlign, buffer);
-        if (!entry) {
-            mContext.getDiagnostics()->error(
-                    DiagMessage() << "failed to write resources.arsc to archive");
-            return false;
+        if (writer->startEntry("resources.arsc", ArchiveEntry::kAlign)) {
+            if (writer->writeEntry(buffer)) {
+                if (writer->finishEntry()) {
+                    return true;
+                }
+            }
         }
-        return true;
+
+        mContext.getDiagnostics()->error(
+                DiagMessage() << "failed to write resources.arsc to archive");
+        return false;
     }
 
     bool flattenXml(xml::XmlResource* xmlRes, const StringPiece& path, Maybe<size_t> maxSdkLevel,
@@ -320,13 +311,17 @@
             return false;
         }
 
-        ArchiveEntry* entry = writer->writeEntry(path, ArchiveEntry::kCompress, buffer);
-        if (!entry) {
-            mContext.getDiagnostics()->error(
-                    DiagMessage() << "failed to write " << path << " to archive");
-            return false;
+
+        if (writer->startEntry(path, ArchiveEntry::kCompress)) {
+            if (writer->writeEntry(buffer)) {
+                if (writer->finishEntry()) {
+                    return true;
+                }
+            }
         }
-        return true;
+        mContext.getDiagnostics()->error(
+                DiagMessage() << "failed to write " << path << " to archive");
+        return false;
     }
 
     bool writeJavaFile(ResourceTable* table, const StringPiece16& packageNameToGenerate,
@@ -412,34 +407,44 @@
         return true;
     }
 
-    bool mergeResourceTable(const std::string& input, bool override) {
+    bool mergeResourceTable(io::IFile* file, bool override) {
         if (mOptions.verbose) {
-            mContext.getDiagnostics()->note(DiagMessage() << "linking " << input);
+            mContext.getDiagnostics()->note(DiagMessage() << "linking " << file->getSource());
         }
 
-        std::unique_ptr<ResourceTable> table = loadTable(input);
+        std::unique_ptr<io::IData> data = file->openAsData();
+        if (!data) {
+            mContext.getDiagnostics()->error(DiagMessage(file->getSource())
+                                             << "failed to open file");
+            return false;
+        }
+
+        std::unique_ptr<ResourceTable> table = loadTable(file->getSource(), data->data(),
+                                                         data->size());
         if (!table) {
             return false;
         }
 
-        if (!mTableMerger->merge(Source(input), table.get(), override)) {
+        if (!mTableMerger->merge(file->getSource(), table.get(), override)) {
             return false;
         }
         return true;
     }
 
-    bool mergeCompiledFile(const std::string& input, ResourceFile&& file, bool override) {
-        if (file.name.package.empty()) {
-            file.name.package = mContext.getCompilationPackage().toString();
+    bool mergeCompiledFile(io::IFile* file, std::unique_ptr<ResourceFile> fileDesc, bool override) {
+        // Apply the package name used for this compilation phase if none was specified.
+        if (fileDesc->name.package.empty()) {
+            fileDesc->name.package = mContext.getCompilationPackage().toString();
         }
 
-        ResourceNameRef resName = file.name;
-
-        Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(file.name);
+        // Mangle the name if necessary.
+        ResourceNameRef resName = fileDesc->name;
+        Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(fileDesc->name);
         if (mangledName) {
             resName = mangledName.value();
         }
 
+        // If we are overriding resources, we supply a custom resolver function.
         std::function<int(Value*,Value*)> resolver;
         if (override) {
             resolver = [](Value* a, Value* b) -> int {
@@ -456,14 +461,14 @@
         }
 
         // Add this file to the table.
-        if (!mFinalTable.addFileReference(resName, file.config, file.source,
-                                          util::utf8ToUtf16(buildResourceFileName(file)),
+        if (!mFinalTable.addFileReference(resName, fileDesc->config, fileDesc->source,
+                                          util::utf8ToUtf16(buildResourceFileName(*fileDesc)),
                                           resolver, mContext.getDiagnostics())) {
             return false;
         }
 
         // Add the exports of this file to the table.
-        for (SourcedResourceName& exportedSymbol : file.exportedSymbols) {
+        for (SourcedResourceName& exportedSymbol : fileDesc->exportedSymbols) {
             if (exportedSymbol.name.package.empty()) {
                 exportedSymbol.name.package = mContext.getCompilationPackage().toString();
             }
@@ -477,32 +482,78 @@
             }
 
             std::unique_ptr<Id> id = util::make_unique<Id>();
-            id->setSource(file.source.withLine(exportedSymbol.line));
+            id->setSource(fileDesc->source.withLine(exportedSymbol.line));
             bool result = mFinalTable.addResourceAllowMangled(resName, {}, std::move(id),
-                    mContext.getDiagnostics());
+                                                              mContext.getDiagnostics());
             if (!result) {
                 return false;
             }
         }
 
-        mFilesToProcess.insert(FileToProcess{ std::move(file), Source(input) });
+        // Now add this file for later processing. Once the table is assigned IDs, we can compile
+        // this file.
+        mFilesToProcess.insert(FileToProcess{ std::move(fileDesc), file });
         return true;
     }
 
-    bool processFile(const std::string& input, bool override) {
-        if (util::stringEndsWith<char>(input, ".apk")) {
-            return mergeStaticLibrary(input);
-        } else if (util::stringEndsWith<char>(input, ".arsc.flat")) {
-            return mergeResourceTable(input, override);
-        } else if (Maybe<ResourceFile> maybeF = loadFileExportHeader(input)) {
-            return mergeCompiledFile(input, std::move(maybeF.value()), override);
+    /**
+     * Creates an io::IFileCollection from the ZIP archive and processes the files within.
+     */
+    bool mergeArchive(const std::string& input, bool override) {
+        std::string errorStr;
+        std::unique_ptr<io::ZipFileCollection> collection = io::ZipFileCollection::create(
+                input, &errorStr);
+        if (!collection) {
+            mContext.getDiagnostics()->error(DiagMessage(input) << errorStr);
+            return false;
+        }
+
+        bool error = false;
+        for (const std::unique_ptr<io::IFile>& file : *collection) {
+            if (!processFile(file.get(), override)) {
+                error = true;
+            }
+        }
+
+        // Make sure to move the collection into the set of IFileCollections.
+        mCollections.push_back(std::move(collection));
+        return !error;
+    }
+
+    bool processFile(const std::string& path, bool override) {
+        if (util::stringEndsWith<char>(path, ".flata")) {
+            return mergeArchive(path, override);
+        }
+
+        io::IFile* file = mFileCollection->insertFile(path);
+        return processFile(file, override);
+    }
+
+    bool processFile(io::IFile* file, bool override) {
+        const Source& src = file->getSource();
+        if (util::stringEndsWith<char>(src.path, ".arsc.flat")) {
+            return mergeResourceTable(file, override);
+        } else {
+            // Try opening the file and looking for an Export header.
+            std::unique_ptr<io::IData> data = file->openAsData();
+            if (!data) {
+                mContext.getDiagnostics()->error(DiagMessage(src) << "failed to open");
+                return false;
+            }
+
+            std::unique_ptr<ResourceFile> resourceFile = loadFileExportHeader(
+                    src, data->data(), data->size(), mContext.getDiagnostics());
+            if (resourceFile) {
+                return mergeCompiledFile(file, std::move(resourceFile), override);
+            }
         }
         return false;
     }
 
     int run(const std::vector<std::string>& inputFiles) {
         // Load the AndroidManifest.xml
-        std::unique_ptr<xml::XmlResource> manifestXml = loadXml(mOptions.manifestPath);
+        std::unique_ptr<xml::XmlResource> manifestXml = loadXml(mOptions.manifestPath,
+                                                                mContext.getDiagnostics());
         if (!manifestXml) {
             return 1;
         }
@@ -648,20 +699,30 @@
         }
 
         for (const FileToProcess& file : mFilesToProcess) {
-            if (file.file.name.type != ResourceType::kRaw &&
-                    util::stringEndsWith<char>(file.source.path, ".xml.flat")) {
+            const StringPiece path = file.file->getSource().path;
+
+            if (file.fileExport->name.type != ResourceType::kRaw &&
+                    util::stringEndsWith<char>(path, ".xml.flat")) {
                 if (mOptions.verbose) {
-                    mContext.getDiagnostics()->note(DiagMessage()
-                                                    << "linking " << file.source.path);
+                    mContext.getDiagnostics()->note(DiagMessage() << "linking " << path);
+                }
+
+                std::unique_ptr<io::IData> data = file.file->openAsData();
+                if (!data) {
+                    mContext.getDiagnostics()->error(DiagMessage(file.file->getSource())
+                                                     << "failed to open file");
+                    return 1;
                 }
 
                 std::unique_ptr<xml::XmlResource> xmlRes = loadBinaryXmlSkipFileExport(
-                        file.source.path);
+                        file.file->getSource(), data->data(), data->size(),
+                        mContext.getDiagnostics());
                 if (!xmlRes) {
                     return 1;
                 }
 
-                xmlRes->file = std::move(file.file);
+                // Move the file description over.
+                xmlRes->file = std::move(*file.fileExport);
 
                 XmlReferenceLinker xmlLinker;
                 if (xmlLinker.consume(&mContext, xmlRes.get())) {
@@ -689,12 +750,13 @@
                                                                     xmlRes->file.config,
                                                                     sdkLevel)) {
                                 xmlRes->file.config.sdkVersion = sdkLevel;
-                                if (!mFinalTable.addFileReference(xmlRes->file.name,
-                                                                  xmlRes->file.config,
-                                                                  xmlRes->file.source,
-                                                                  util::utf8ToUtf16(
-                                                                     buildResourceFileName(xmlRes->file)),
-                                                             mContext.getDiagnostics())) {
+                                bool added = mFinalTable.addFileReference(
+                                        xmlRes->file.name,
+                                        xmlRes->file.config,
+                                        xmlRes->file.source,
+                                        util::utf8ToUtf16(buildResourceFileName(xmlRes->file)),
+                                        mContext.getDiagnostics());
+                                if (!added) {
                                     error = true;
                                     continue;
                                 }
@@ -712,11 +774,10 @@
                 }
             } else {
                 if (mOptions.verbose) {
-                    mContext.getDiagnostics()->note(DiagMessage() << "copying "
-                                                    << file.source.path);
+                    mContext.getDiagnostics()->note(DiagMessage() << "copying " << path);
                 }
 
-                if (!copyFileToArchive(file.source.path, buildResourceFileName(file.file), 0,
+                if (!copyFileToArchive(file.file, buildResourceFileName(*file.fileExport), 0,
                                        archiveWriter.get())) {
                     error = true;
                 }
@@ -802,14 +863,18 @@
     ResourceTable mFinalTable;
     std::unique_ptr<TableMerger> mTableMerger;
 
+    io::FileCollection* mFileCollection;
+    std::vector<std::unique_ptr<io::IFileCollection>> mCollections;
+
     struct FileToProcess {
-        ResourceFile file;
-        Source source;
+        std::unique_ptr<ResourceFile> fileExport;
+        io::IFile* file;
     };
 
     struct FileToProcessComparator {
         bool operator()(const FileToProcess& a, const FileToProcess& b) {
-            return std::tie(a.file.name, a.file.config) < std::tie(b.file.name, b.file.config);
+            return std::tie(a.fileExport->name, a.fileExport->config) <
+                    std::tie(b.fileExport->name, b.fileExport->config);
         }
     };