DO NOT MERGE - Merge Android 10 into master

Bug: 139893257
Change-Id: I051470350ba70a77ec5d78ab5cc9ff02bf4aa4b2
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..764dc49
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,104 @@
+// Copyright (C) 2019 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.
+
+java_defaults {
+    name: "documentsui_defaults",
+
+    static_libs: [
+        "androidx.appcompat_appcompat",
+        "androidx.legacy_legacy-support-core-ui",
+        "androidx.legacy_legacy-support-v13",
+        "androidx.legacy_legacy-support-v4",
+        "androidx.recyclerview_recyclerview",
+        "androidx.recyclerview_recyclerview-selection",
+        "androidx.transition_transition",
+        "apache-commons-compress",
+        "com.google.android.material_material",
+        "guava",
+    ],
+
+    privileged: true,
+
+    certificate: "platform",
+
+    optimize: {
+        proguard_flags_files: ["proguard.flags"],
+    },
+
+    sdk_version: "system_current",
+    min_sdk_version: "28",
+    target_sdk_version: "28",
+}
+
+filegroup {
+    name: "DocumentsUI-srcs",
+    srcs: [
+        "src/**/*.java",
+	":statslog-docsui-java-gen",
+    ],
+}
+
+java_library {
+    name: "docsui-statsd",
+    srcs: [
+        ":statslog-docsui-java-gen",
+    ],
+}
+
+genrule {
+    name: "statslog-docsui-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module docsui --javaPackage com.android.documentsui --javaClass DocumentsStatsLog",
+    out: ["com/android/documentsui/DocumentsStatsLog.java"],
+}
+
+android_library {
+    name: "DocumentsUI-res-lib",
+
+    manifest: "AndroidManifest.xml",
+
+    static_libs: [
+        "androidx.appcompat_appcompat",
+        "com.google.android.material_material",
+    ],
+
+    resource_dirs: [
+        "res",
+    ],
+
+    aaptflags: [
+        "--auto-add-overlay",
+    ],
+
+    min_sdk_version: "28",
+    target_sdk_version: "28",
+}
+
+android_app {
+    name: "DocumentsUI",
+
+    defaults: ["documentsui_defaults"],
+
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        ":DocumentsUI-srcs",
+    ],
+
+    resource_dirs: [
+        "res",
+    ],
+
+    required: ["privapp_whitelist_com.android.documentsui"],
+}
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index a0b633a..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-########################
-# Complete DocumentsUI app:
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := DocumentsUI
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_FULL_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml
-
-include $(LOCAL_PATH)/build_apk.mk
-
-########################
-# Minimal DocumentsUI app (supports Scoped Directory Access only):
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-        src/com/android/documentsui/ScopedAccessActivity.java \
-        src/com/android/documentsui/ScopedAccessPackageReceiver.java \
-        src/com/android/documentsui/ScopedAccessProvider.java \
-        src/com/android/documentsui/ScopedAccessMetrics.java \
-        src/com/android/documentsui/archives/Archive.java \
-        src/com/android/documentsui/archives/ArchiveId.java \
-        src/com/android/documentsui/archives/ArchivesProvider.java \
-        src/com/android/documentsui/archives/Loader.java \
-        src/com/android/documentsui/archives/Proxy.java \
-        src/com/android/documentsui/archives/ReadableArchive.java \
-        src/com/android/documentsui/archives/WriteableArchive.java \
-        src/com/android/documentsui/base/Providers.java \
-        src/com/android/documentsui/base/SharedMinimal.java \
-        src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
-
-LOCAL_PACKAGE_NAME := DocumentsUIMinimal
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/minimal/res
-LOCAL_FULL_MANIFEST_FILE := $(LOCAL_PATH)/minimal/AndroidManifest.xml
-
-include $(LOCAL_PATH)/build_apk.mk
-
-# Include makefiles for tests and libraries under the current path
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c264285..a2b01f3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -19,17 +19,13 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.documentsui">
 
-    <uses-permission android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS" />
-    <uses-permission android:name="android.permission.FORCE_PERSISTABLE_URI_PERMISSIONS" />
     <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
     <uses-permission android:name="android.permission.REMOVE_TASKS" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.CACHE_CONTENT" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
-    <uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
-
-    <uses-sdk android:minSdkVersion="21"/>
+    <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
 
     <application
         android:name=".DocumentsApplication"
@@ -96,6 +92,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.APP_FILES" />
             </intent-filter>
             <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
         </activity-alias>
@@ -119,7 +116,7 @@
             </intent-filter>
         </activity>
 
-        <activity-alias android:name="ViewDownloadsActivity"
+        <activity-alias android:name=".ViewDownloadsActivity"
                         android:targetActivity=".files.FilesActivity"
                         android:enabled="@bool/handle_view_downloads_intent">
             <intent-filter>
@@ -138,18 +135,16 @@
         </activity>
 
         <provider
-            android:name=".ScopedAccessProvider"
-            android:authorities="com.android.documentsui.scopedAccess"
-            android:permission="android.permission.MANAGE_SCOPED_ACCESS_DIRECTORY_PERMISSIONS"
-            android:exported="true">
-        </provider>
-
-        <provider
             android:name=".picker.LastAccessedProvider"
             android:authorities="com.android.documentsui.lastAccessed"
             android:exported="false"/>
 
         <provider
+            android:name=".picker.PickCountRecordProvider"
+            android:authorities="com.android.documentsui.pickCountRecord"
+            android:exported="false"/>
+
+        <provider
             android:name=".archives.ArchivesProvider"
             android:authorities="com.android.documentsui.archives"
             android:grantUriPermissions="true"
@@ -174,6 +169,12 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name=".PreBootReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.PRE_BOOT_COMPLETED" />
+            </intent-filter>
+        </receiver>
+
         <!-- Run FileOperationService in a separate process so that we can use FileLock class to
             wait until jumbo clip is done writing to disk before reading it. See ClipStorage for
             details. -->
@@ -186,7 +187,7 @@
         <activity
             android:name=".selection.demo.SelectionDemoActivity"
             android:label="Selection Demo"
-            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
+            android:theme="@style/DocumentsTheme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..e731138
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,16 @@
+[Hook Scripts]
+checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
+
+api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT}
+
+strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
+
+hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
+
+hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
+
+ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
+
+owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
+
+shell_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^packages/Shell/"
diff --git a/app-perf-tests/Android.bp b/app-perf-tests/Android.bp
new file mode 100644
index 0000000..9ed4c97
--- /dev/null
+++ b/app-perf-tests/Android.bp
@@ -0,0 +1,30 @@
+android_test {
+    name: "DocumentsUIAppPerfTests",
+
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        "src/**/*.java",
+    ],
+
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+
+    static_libs: [
+        "androidx.legacy_legacy-support-v4",
+        "mockito-target",
+        "ub-uiautomator",
+    ],
+
+    platform_apis: true,
+
+    instrumentation_for: "DocumentsUI",
+
+    certificate: "platform",
+
+    test_suites: ["device-tests"],
+
+    //sdk_version: "current",
+}
diff --git a/app-perf-tests/Android.mk b/app-perf-tests/Android.mk
deleted file mode 100644
index f7d67fd..0000000
--- a/app-perf-tests/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-#LOCAL_SDK_VERSION := current
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_STATIC_ANDROID_LIBRARIES := android-support-v4
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    mockito-target \
-    ub-uiautomator
-
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := DocumentsUIAppPerfTests
-LOCAL_INSTRUMENTATION_FOR := DocumentsUI
-
-LOCAL_COMPATIBILITY_SUITE += device-tests
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
-
diff --git a/build_apk.mk b/build_apk.mk
index 19d9c62..b66e66e 100644
--- a/build_apk.mk
+++ b/build_apk.mk
@@ -1,16 +1,19 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_PRIVILEGED_MODULE := true
 
-LOCAL_STATIC_JAVA_LIBRARIES += guava
+LOCAL_STATIC_JAVA_LIBRARIES += guava \
+        apache-commons-compress \
+        docsui-statsd
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
-        android-support-core-ui \
-        android-support-v4 \
-        android-support-v7-appcompat \
-        android-support-v13 \
-        $(ANDROID_SUPPORT_DESIGN_TARGETS) \
-        android-support-transition \
-        android-support-v7-recyclerview
+        androidx.legacy_legacy-support-core-ui \
+        androidx.legacy_legacy-support-v4 \
+        androidx.appcompat_appcompat \
+        androidx.legacy_legacy-support-v13 \
+        androidx.transition_transition \
+        androidx.recyclerview_recyclerview \
+        androidx.recyclerview_recyclerview-selection \
+        com.google.android.material_material
 
 LOCAL_USE_AAPT2 := true
 
@@ -25,4 +28,8 @@
 LOCAL_CERTIFICATE := platform
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
+# TODO: build against public API as part of b/110959821
+LOCAL_PRIVATE_PLATFORM_APIS := true
+#LOCAL_SDK_VERSION := current
+
 include $(BUILD_PACKAGE)
diff --git a/minimal/AndroidManifest.xml b/minimal/AndroidManifest.xml
deleted file mode 100644
index 33df1ba..0000000
--- a/minimal/AndroidManifest.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2007-2017 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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.documentsui">
-
-    <uses-permission android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS" />
-    <uses-permission android:name="android.permission.FORCE_PERSISTABLE_URI_PERMISSIONS" />
-    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
-    <uses-permission android:name="android.permission.CACHE_CONTENT" />
-
-    <!-- This is a minimal version of the DocumentsUI app supporting ScopedDirectoryAccess
-         only. It is part of the Android TV build. -->
-    <application
-        android:label="@string/app_label"
-        android:icon="@drawable/app_icon"
-        android:supportsRtl="true"
-        android:allowBackup="false"
-        android:fullBackupOnly="false">
-
-        <activity
-            android:name=".ScopedAccessActivity"
-            android:theme="@android:style/Theme.Translucent.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.os.storage.action.OPEN_EXTERNAL_DIRECTORY" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
-        <receiver android:name=".ScopedAccessPackageReceiver">
-            <intent-filter>
-                <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
-                <action android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
-                <data android:scheme="package" />
-            </intent-filter>
-        </receiver>
-
-        <provider
-            android:name=".ScopedAccessProvider"
-            android:authorities="com.android.documentsui.scopedAccess"
-            android:permission="android.permission.MANAGE_SCOPED_ACCESS_DIRECTORY_PERMISSIONS"
-            android:exported="true">
-        </provider>
-
-    </application>
-</manifest>
diff --git a/minimal/res/layout/dialog_open_scoped_directory.xml b/minimal/res/layout/dialog_open_scoped_directory.xml
deleted file mode 100644
index cb39206..0000000
--- a/minimal/res/layout/dialog_open_scoped_directory.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:theme="@style/Theme.AppCompat.Light.Dialog.Alert"
-    android:orientation="vertical"
-    android:paddingEnd="24dp"
-    android:paddingStart="24dp" >
-
-    <TextView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/message"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingEnd="24dp"
-        android:paddingStart="32dp"
-        android:paddingTop="24dp">
-    </TextView>
-
-    <CheckBox
-        android:id="@+id/do_not_ask_checkbox"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="16dip"
-        android:text="@string/never_ask_again"
-        android:textColor="?android:attr/textColorSecondary"
-        android:visibility="gone" />
-</LinearLayout>
diff --git a/minimal/res/mipmap-anydpi/ic_app_icon.xml b/minimal/res/mipmap-anydpi/ic_app_icon.xml
deleted file mode 100644
index cd4fa58..0000000
--- a/minimal/res/mipmap-anydpi/ic_app_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@color/app_icon_background"/>
-    <foreground android:drawable="@mipmap/ic_launcher_icon_foreground"/>
-</adaptive-icon>
diff --git a/minimal/res/mipmap-hdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-hdpi/ic_launcher_icon_foreground.png
deleted file mode 100644
index 992c44e..0000000
--- a/minimal/res/mipmap-hdpi/ic_launcher_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/minimal/res/mipmap-mdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-mdpi/ic_launcher_icon_foreground.png
deleted file mode 100644
index 4639ff0..0000000
--- a/minimal/res/mipmap-mdpi/ic_launcher_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/minimal/res/mipmap-xhdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-xhdpi/ic_launcher_icon_foreground.png
deleted file mode 100644
index b992944..0000000
--- a/minimal/res/mipmap-xhdpi/ic_launcher_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/minimal/res/mipmap-xxhdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-xxhdpi/ic_launcher_icon_foreground.png
deleted file mode 100644
index ae44b2f..0000000
--- a/minimal/res/mipmap-xxhdpi/ic_launcher_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/minimal/res/mipmap-xxxhdpi/ic_launcher_icon_foreground.png b/minimal/res/mipmap-xxxhdpi/ic_launcher_icon_foreground.png
deleted file mode 100644
index 85150eb..0000000
--- a/minimal/res/mipmap-xxxhdpi/ic_launcher_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/minimal/res/values/colors.xml b/minimal/res/values/colors.xml
deleted file mode 100644
index 61a8150..0000000
--- a/minimal/res/values/colors.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-    <color name="app_icon_background">#ff4688f2</color>
-</resources>
diff --git a/minimal/res/values/strings.xml b/minimal/res/values/strings.xml
deleted file mode 100644
index bcffd6b..0000000
--- a/minimal/res/values/strings.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Title of the Files application [CHAR LIMIT=32] -->
-    <string name="files_label">Files</string>
-
-    <!-- Title of the documents application [CHAR LIMIT=32] -->
-    <string name="app_label">@string/files_label</string>
-
-    <!-- Title of the documents application [CHAR LIMIT=32] -->
-    <string name="launcher_label">@string/files_label</string>
-
-    <!-- Text in an alert dialog asking user to grant app access to a given directory in an external storage volume -->
-    <string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
-        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory on
-        <xliff:g id="storage" example="SD Card"><i>^3</i></xliff:g>?</string>
-    <!-- Text in an alert dialog asking user to grant app access to a given directory in the internal storage -->
-    <string name="open_external_dialog_request_primary_volume">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
-        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> directory?</string>
-    <!-- Text in an alert dialog asking user to grant app access to all data in an external storage volume -->
-    <string name="open_external_dialog_root_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
-        access to your data, including photos and videos, on <xliff:g id="storage" example="SD Card"><i>^2</i></xliff:g>?</string>
-    <!-- Checkbox that allows user to not be questioned about the directory access request again -->
-    <string name="never_ask_again">Don\'t ask again</string>
-    <!-- Text in the button asking user to allow access to a given directory. -->
-    <string name="allow">Allow</string>
-    <!-- Text in the button asking user to deny access to a given directory. -->
-    <string name="deny">Deny</string>
-
-    <!-- Error message shown when an archive fails to load -->
-    <string name="archive_loading_failed">Unable to open archive for browsing. File is either corrupt, or an unsupported format.</string>
-
-</resources>
diff --git a/perf-tests/Android.bp b/perf-tests/Android.bp
new file mode 100644
index 0000000..963a6da
--- /dev/null
+++ b/perf-tests/Android.bp
@@ -0,0 +1,34 @@
+android_test {
+    name: "DocumentsUIPerfTests",
+
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        ":DocumentsUIPerfTests-files",
+        "src/**/*.java",
+    ],
+
+    resource_dirs: [
+        "res",
+    ],
+
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+    ],
+
+    static_libs: [
+        "androidx.legacy_legacy-support-v4",
+        "androidx.test.espresso.core",
+        "mockito-target",
+        "ub-janktesthelper",
+        "ub-uiautomator",
+    ],
+
+    platform_apis: true,
+
+    instrumentation_for: "DocumentsUI",
+
+    certificate: "platform",
+}
diff --git a/perf-tests/Android.mk b/perf-tests/Android.mk
deleted file mode 100644
index 731a8fa..0000000
--- a/perf-tests/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    $(call all-java-files-under, ../tests/common/com/android/documentsui) \
-    ../tests/functional/com/android/documentsui/ActivityTest.java
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
-LOCAL_STATIC_ANDROID_LIBRARIES := android-support-v4
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    mockito-target \
-    ub-uiautomator \
-    ub-janktesthelper \
-    espresso-core
-
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := DocumentsUIPerfTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_INSTRUMENTATION_FOR := DocumentsUI
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
-
diff --git a/proguard.flags b/proguard.flags
index 0f33fb2..1d25326 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -13,6 +13,10 @@
 # limitations under the License.
 
 # Keep
--keep public class android.support.v4.view.accessibility.AccessibilityNodeInfoCompat {
-   public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain();
-}
\ No newline at end of file
+-keep public class androidx.core.view.accessibility.AccessibilityNodeInfoCompat {
+   public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat obtain();
+}
+
+# To prevent class not found exception in org.brotli.dec.Dictionary
+-keep final class org.brotli.dec.DictionaryData
+
diff --git a/res/anim/progress_indeterminate_horizontal_rect1.xml b/res/anim/progress_indeterminate_horizontal_rect1.xml
new file mode 100644
index 0000000..4bca4e5
--- /dev/null
+++ b/res/anim/progress_indeterminate_horizontal_rect1.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="2000"
+        android:propertyXName="translateX"
+        android:pathData="M -522.59998,0 c 48.89972,0 166.02656,0 301.21729,0 c 197.58128,0 420.9827,0 420.9827,0 "
+        android:interpolator="@interpolator/progress_indeterminate_horizontal_rect1_translatex"
+        android:repeatCount="infinite" />
+    <objectAnimator
+        android:duration="2000"
+        android:propertyYName="scaleX"
+        android:pathData="M 0 0.1 L 1 0.826849212646 L 2 0.1"
+        android:interpolator="@interpolator/progress_indeterminate_horizontal_rect1_scalex"
+        android:repeatCount="infinite" />
+</set>
diff --git a/res/anim/progress_indeterminate_horizontal_rect2.xml b/res/anim/progress_indeterminate_horizontal_rect2.xml
new file mode 100644
index 0000000..ff1e67d
--- /dev/null
+++ b/res/anim/progress_indeterminate_horizontal_rect2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="2000"
+        android:propertyXName="translateX"
+        android:pathData="M -197.60001,0 c 14.28182,0 85.07782,0 135.54689,0 c 54.26191,0 90.42461,0 168.24331,0 c 144.72154,0 316.40982,0 316.40982,0 "
+        android:interpolator="@interpolator/progress_indeterminate_horizontal_rect2_translatex"
+        android:repeatCount="infinite" />
+    <objectAnimator
+        android:duration="2000"
+        android:propertyYName="scaleX"
+        android:pathData="M 0.0,0.1 L 1.0,0.571379510698 L 2.0,0.909950256348 L 3.0,0.1"
+        android:interpolator="@interpolator/progress_indeterminate_horizontal_rect2_scalex"
+        android:repeatCount="infinite" />
+</set>
diff --git a/res/color/item_eject_icon.xml b/res/color/item_action_icon.xml
similarity index 88%
rename from res/color/item_eject_icon.xml
rename to res/color/item_action_icon.xml
index 2f04978..5de0cb6 100644
--- a/res/color/item_eject_icon.xml
+++ b/res/color/item_action_icon.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
         android:alpha="@dimen/root_icon_disabled_alpha"
-        android:color="@color/root_icon_color" />
-    <item android:color="@color/root_icon_color" />
+        android:color="?android:colorControlNormal" />
+    <item android:color="?android:colorControlNormal" />
 </selector>
diff --git a/res/color/item_details.xml b/res/color/item_details.xml
index 2915eaa..970e55d 100644
--- a/res/color/item_details.xml
+++ b/res/color/item_details.xml
@@ -17,5 +17,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_enabled="true"
-        android:color="@color/item_doc_details" />
+        android:color="?android:textColorSecondary" />
 </selector>
diff --git a/res/color/item_doc_grid_border.xml b/res/color/item_doc_grid_border.xml
index d75a462..b535aed 100644
--- a/res/color/item_doc_grid_border.xml
+++ b/res/color/item_doc_grid_border.xml
@@ -18,7 +18,10 @@
     <item
         android:state_focused="true"
         android:state_selected="false"
-        android:color="?android:attr/colorAccent"/>
+        android:color="?android:attr/colorPrimary"/>
     <item
-        android:color="@android:color/transparent" />
+        android:state_selected="true"
+        android:color="?android:attr/colorPrimary"/>
+    <item
+        android:color="@android:color/transparent"/>
 </selector>
diff --git a/res/color/item_doc_grid_tint.xml b/res/color/item_doc_grid_tint.xml
index 23392ca..2c48e96 100644
--- a/res/color/item_doc_grid_tint.xml
+++ b/res/color/item_doc_grid_tint.xml
@@ -17,7 +17,7 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_activated="true"
-        android:color="@color/item_grid_tint"
+        android:color="?android:colorPrimary"
         android:alpha=".15" />
     <item
         android:color="@android:color/transparent" />
diff --git a/res/color/item_root_icon.xml b/res/color/item_root_icon.xml
index 8055e04..456d1b4 100644
--- a/res/color/item_root_icon.xml
+++ b/res/color/item_root_icon.xml
@@ -17,8 +17,8 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_activated="false"
-        android:color="@color/root_icon_color" />
+        android:color="?android:colorControlNormal" />
     <item
         android:state_activated="true"
-        android:color="@color/root_activated_color" />
+        android:color="?android:colorControlActivated" />
 </selector>
diff --git a/res/color/item_root_primary_text.xml b/res/color/item_root_primary_text.xml
index 6aebe2d..62a620c 100644
--- a/res/color/item_root_primary_text.xml
+++ b/res/color/item_root_primary_text.xml
@@ -15,8 +15,8 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:state_focused="true" android:state_activated="true" android:color="@color/root_activated_color" />
-  <item android:state_focused="false" android:state_activated="true" android:color="@color/root_activated_color" />
-    <item android:state_enabled="false" android:alpha="0.5" android:color="@color/root_title_color" />
-    <item android:color="@color/root_title_color" />
+    <item android:state_focused="true" android:state_activated="true" android:color="?android:colorControlActivated" />
+    <item android:state_focused="false" android:state_activated="true" android:color="?android:colorControlActivated" />
+    <item android:state_enabled="false" android:alpha="0.5" android:color="?android:textColorPrimary" />
+    <item android:color="?android:textColorPrimary" />
 </selector>
diff --git a/res/color/item_root_secondary_text.xml b/res/color/item_root_secondary_text.xml
new file mode 100644
index 0000000..44086ef
--- /dev/null
+++ b/res/color/item_root_secondary_text.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_activated="true" android:color="?android:colorPrimary" />
+    <item android:state_focused="false" android:state_activated="true" android:color="?android:colorPrimary" />
+    <item android:state_enabled="false" android:alpha="0.5" android:color="?android:textColorSecondary" />
+    <item android:color="?android:textColorSecondary" />
+</selector>
diff --git a/res/color/search_chip_background_color.xml b/res/color/search_chip_background_color.xml
new file mode 100644
index 0000000..c94d155
--- /dev/null
+++ b/res/color/search_chip_background_color.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 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
+
+      https://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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="?android:attr/colorSecondary"/>
+    <item android:state_enabled="true" android:color="?android:attr/colorBackground"/>
+    <item android:state_enabled="false" android:color="@color/chip_background_disable_color"/>
+</selector>
\ No newline at end of file
diff --git a/res/color/search_chip_ripple_color.xml b/res/color/search_chip_ripple_color.xml
new file mode 100644
index 0000000..985b6cc
--- /dev/null
+++ b/res/color/search_chip_ripple_color.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 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
+
+      https://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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Selected. -->
+    <item android:state_pressed="true" android:state_selected="true"
+          android:alpha="0.16" android:color="?android:colorPrimary"/>
+    <item android:state_focused="true" android:state_hovered="true" android:state_selected="true"
+          android:alpha="0.16" android:color="?android:colorPrimary"/>
+    <item android:state_focused="true" android:state_selected="true"
+          android:alpha="0.12" android:color="?android:colorPrimary"/>
+    <item android:state_hovered="true" android:state_selected="true"
+          android:alpha="0.04" android:color="?android:colorPrimary"/>
+    <item android:state_selected="true"
+          android:alpha="0.00" android:color="?android:colorPrimary"/>
+
+    <!-- Unselected. -->
+    <item android:state_pressed="true" android:alpha="0.16" android:color="?android:textColorSecondary"/>
+    <item android:state_focused="true" android:state_hovered="true"
+          android:alpha="0.16" android:color="?android:textColorSecondary"/>
+    <item android:state_focused="true" android:alpha="0.12" android:color="?android:textColorSecondary"/>
+    <item android:state_hovered="true" android:alpha="0.04" android:color="?android:textColorSecondary"/>
+    <item android:alpha="0.00" android:color="?android:textColorSecondary"/>
+</selector>
\ No newline at end of file
diff --git a/res/color/search_chip_stroke_color.xml b/res/color/search_chip_stroke_color.xml
new file mode 100644
index 0000000..be16935
--- /dev/null
+++ b/res/color/search_chip_stroke_color.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 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
+
+      https://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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="@android:color/transparent"/>
+    <item android:state_pressed="true" android:color="@android:color/transparent"/>
+    <item android:state_enabled="true" android:color="?android:strokeColor"/>
+    <item android:state_enabled="false" android:color="@android:color/transparent"/>
+</selector>
\ No newline at end of file
diff --git a/res/color/search_chip_text_color.xml b/res/color/search_chip_text_color.xml
new file mode 100644
index 0000000..0457ba2
--- /dev/null
+++ b/res/color/search_chip_text_color.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 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
+
+      https://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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="?android:colorPrimary"/>
+    <item android:state_enabled="true" android:color="?android:textColorSecondary"/>
+    <item android:state_enabled="false" android:color="?android:textColorSecondary" android:alpha="0.3"/>
+</selector>
\ No newline at end of file
diff --git a/res/color/item_title.xml b/res/color/sort_list_text.xml
similarity index 74%
copy from res/color/item_title.xml
copy to res/color/sort_list_text.xml
index d1760d0..16f16a2 100644
--- a/res/color/item_title.xml
+++ b/res/color/sort_list_text.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -13,12 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_enabled="true"
-        android:color="@color/item_doc_title" />
+        android:state_checked="true"
+        android:color="?android:attr/colorPrimary"/>
     <item
-        android:state_enabled="false"
-        android:color="@color/item_doc_title_disabled"/>
-</selector>
+        android:color="?android:attr/textColorPrimary"/>
+</selector>
\ No newline at end of file
diff --git a/res/drawable-hdpi/ic_breadcrumb_arrow_am_alpha.png b/res/drawable-hdpi/ic_breadcrumb_arrow_am_alpha.png
deleted file mode 100644
index 67f890c..0000000
--- a/res/drawable-hdpi/ic_breadcrumb_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_cab_cancel_alpha.png b/res/drawable-hdpi/ic_cab_cancel_alpha.png
deleted file mode 100644
index 1a9cd75..0000000
--- a/res/drawable-hdpi/ic_cab_cancel_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialog_alert_alpha.png b/res/drawable-hdpi/ic_dialog_alert_alpha.png
deleted file mode 100644
index 4c3d9a4..0000000
--- a/res/drawable-hdpi/ic_dialog_alert_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialog_info_alpha.png b/res/drawable-hdpi/ic_dialog_info_alpha.png
deleted file mode 100644
index da56077..0000000
--- a/res/drawable-hdpi/ic_dialog_info_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_hamburger_alpha.png b/res/drawable-hdpi/ic_hamburger_alpha.png
deleted file mode 100644
index 3f8ebd6..0000000
--- a/res/drawable-hdpi/ic_hamburger_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_compress_alpha.png b/res/drawable-hdpi/ic_menu_compress_alpha.png
deleted file mode 100644
index 94d0646..0000000
--- a/res/drawable-hdpi/ic_menu_compress_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_copy_alpha.png b/res/drawable-hdpi/ic_menu_copy_alpha.png
deleted file mode 100644
index 9a9e570..0000000
--- a/res/drawable-hdpi/ic_menu_copy_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_delete_alpha.png b/res/drawable-hdpi/ic_menu_delete_alpha.png
deleted file mode 100644
index dbbb602..0000000
--- a/res/drawable-hdpi/ic_menu_delete_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_extract_alpha.png b/res/drawable-hdpi/ic_menu_extract_alpha.png
deleted file mode 100644
index c05764d..0000000
--- a/res/drawable-hdpi/ic_menu_extract_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_new_folder_am_alpha.png b/res/drawable-hdpi/ic_menu_new_folder_am_alpha.png
deleted file mode 100644
index 1d25a2d..0000000
--- a/res/drawable-hdpi/ic_menu_new_folder_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_search_alpha.png b/res/drawable-hdpi/ic_menu_search_alpha.png
deleted file mode 100644
index c593e7a..0000000
--- a/res/drawable-hdpi/ic_menu_search_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_share_am_alpha.png b/res/drawable-hdpi/ic_menu_share_am_alpha.png
deleted file mode 100644
index 20ba480..0000000
--- a/res/drawable-hdpi/ic_menu_share_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_view_grid_alpha.png b/res/drawable-hdpi/ic_menu_view_grid_alpha.png
deleted file mode 100644
index 7e15a8c..0000000
--- a/res/drawable-hdpi/ic_menu_view_grid_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_view_list_alpha.png b/res/drawable-hdpi/ic_menu_view_list_alpha.png
deleted file mode 100644
index c15537a..0000000
--- a/res/drawable-hdpi/ic_menu_view_list_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl/roots_list_border.xml b/res/drawable-ldrtl/roots_list_border.xml
index c8e8457..7f3387a 100644
--- a/res/drawable-ldrtl/roots_list_border.xml
+++ b/res/drawable-ldrtl/roots_list_border.xml
@@ -21,6 +21,6 @@
     <shape android:shape="rectangle">
         <stroke
             android:width="1dp"
-            android:color="@color/drawer_border" />
+            android:color="?android:strokeColor"/>
     </shape>
 </inset>
\ No newline at end of file
diff --git a/res/drawable-mdpi/ic_breadcrumb_arrow_am_alpha.png b/res/drawable-mdpi/ic_breadcrumb_arrow_am_alpha.png
deleted file mode 100644
index 9a048f1..0000000
--- a/res/drawable-mdpi/ic_breadcrumb_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_cab_cancel_alpha.png b/res/drawable-mdpi/ic_cab_cancel_alpha.png
deleted file mode 100644
index 40a1a84..0000000
--- a/res/drawable-mdpi/ic_cab_cancel_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialog_alert_alpha.png b/res/drawable-mdpi/ic_dialog_alert_alpha.png
deleted file mode 100644
index e768d11..0000000
--- a/res/drawable-mdpi/ic_dialog_alert_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialog_info_alpha.png b/res/drawable-mdpi/ic_dialog_info_alpha.png
deleted file mode 100644
index 5ef3dc0..0000000
--- a/res/drawable-mdpi/ic_dialog_info_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_hamburger_alpha.png b/res/drawable-mdpi/ic_hamburger_alpha.png
deleted file mode 100644
index ef2a48c..0000000
--- a/res/drawable-mdpi/ic_hamburger_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_compress_alpha.png b/res/drawable-mdpi/ic_menu_compress_alpha.png
deleted file mode 100644
index bdcd478..0000000
--- a/res/drawable-mdpi/ic_menu_compress_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_copy_alpha.png b/res/drawable-mdpi/ic_menu_copy_alpha.png
deleted file mode 100644
index c94cc28..0000000
--- a/res/drawable-mdpi/ic_menu_copy_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_delete_alpha.png b/res/drawable-mdpi/ic_menu_delete_alpha.png
deleted file mode 100644
index 999aa4c..0000000
--- a/res/drawable-mdpi/ic_menu_delete_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_extract_alpha.png b/res/drawable-mdpi/ic_menu_extract_alpha.png
deleted file mode 100644
index ca7c3c9..0000000
--- a/res/drawable-mdpi/ic_menu_extract_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_new_folder_am_alpha.png b/res/drawable-mdpi/ic_menu_new_folder_am_alpha.png
deleted file mode 100644
index 6e6b870..0000000
--- a/res/drawable-mdpi/ic_menu_new_folder_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_search_alpha.png b/res/drawable-mdpi/ic_menu_search_alpha.png
deleted file mode 100644
index 6b16343..0000000
--- a/res/drawable-mdpi/ic_menu_search_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_share_am_alpha.png b/res/drawable-mdpi/ic_menu_share_am_alpha.png
deleted file mode 100644
index f02d360..0000000
--- a/res/drawable-mdpi/ic_menu_share_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_view_grid_alpha.png b/res/drawable-mdpi/ic_menu_view_grid_alpha.png
deleted file mode 100644
index 5f968d5..0000000
--- a/res/drawable-mdpi/ic_menu_view_grid_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_view_list_alpha.png b/res/drawable-mdpi/ic_menu_view_list_alpha.png
deleted file mode 100644
index 7a8eae9..0000000
--- a/res/drawable-mdpi/ic_menu_view_list_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_breadcrumb_arrow_am_alpha.png b/res/drawable-xhdpi/ic_breadcrumb_arrow_am_alpha.png
deleted file mode 100644
index 073583e..0000000
--- a/res/drawable-xhdpi/ic_breadcrumb_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_cab_cancel_alpha.png b/res/drawable-xhdpi/ic_cab_cancel_alpha.png
deleted file mode 100644
index 6bc4372..0000000
--- a/res/drawable-xhdpi/ic_cab_cancel_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialog_alert_alpha.png b/res/drawable-xhdpi/ic_dialog_alert_alpha.png
deleted file mode 100644
index 2ea6164..0000000
--- a/res/drawable-xhdpi/ic_dialog_alert_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialog_info_alpha.png b/res/drawable-xhdpi/ic_dialog_info_alpha.png
deleted file mode 100644
index 46ed12a..0000000
--- a/res/drawable-xhdpi/ic_dialog_info_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_hamburger_alpha.png b/res/drawable-xhdpi/ic_hamburger_alpha.png
deleted file mode 100644
index 4e0286b..0000000
--- a/res/drawable-xhdpi/ic_hamburger_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_compress_alpha.png b/res/drawable-xhdpi/ic_menu_compress_alpha.png
deleted file mode 100644
index 9b88218..0000000
--- a/res/drawable-xhdpi/ic_menu_compress_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_copy_alpha.png b/res/drawable-xhdpi/ic_menu_copy_alpha.png
deleted file mode 100644
index 1cf76a9..0000000
--- a/res/drawable-xhdpi/ic_menu_copy_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_delete_alpha.png b/res/drawable-xhdpi/ic_menu_delete_alpha.png
deleted file mode 100644
index 796ccd2..0000000
--- a/res/drawable-xhdpi/ic_menu_delete_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_extract_alpha.png b/res/drawable-xhdpi/ic_menu_extract_alpha.png
deleted file mode 100644
index 0567dee..0000000
--- a/res/drawable-xhdpi/ic_menu_extract_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_new_folder_am_alpha.png b/res/drawable-xhdpi/ic_menu_new_folder_am_alpha.png
deleted file mode 100644
index 49272b0..0000000
--- a/res/drawable-xhdpi/ic_menu_new_folder_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_search_alpha.png b/res/drawable-xhdpi/ic_menu_search_alpha.png
deleted file mode 100644
index 6381902..0000000
--- a/res/drawable-xhdpi/ic_menu_search_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_share_am_alpha.png b/res/drawable-xhdpi/ic_menu_share_am_alpha.png
deleted file mode 100644
index 81c80b7..0000000
--- a/res/drawable-xhdpi/ic_menu_share_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_view_grid_alpha.png b/res/drawable-xhdpi/ic_menu_view_grid_alpha.png
deleted file mode 100644
index 630188c..0000000
--- a/res/drawable-xhdpi/ic_menu_view_grid_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_view_list_alpha.png b/res/drawable-xhdpi/ic_menu_view_list_alpha.png
deleted file mode 100644
index 73372f4..0000000
--- a/res/drawable-xhdpi/ic_menu_view_list_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_breadcrumb_arrow_am_alpha.png b/res/drawable-xxhdpi/ic_breadcrumb_arrow_am_alpha.png
deleted file mode 100644
index b96cfd1..0000000
--- a/res/drawable-xxhdpi/ic_breadcrumb_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_cab_cancel_alpha.png b/res/drawable-xxhdpi/ic_cab_cancel_alpha.png
deleted file mode 100644
index 51b4401..0000000
--- a/res/drawable-xxhdpi/ic_cab_cancel_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_dialog_alert_alpha.png b/res/drawable-xxhdpi/ic_dialog_alert_alpha.png
deleted file mode 100644
index ed36f70..0000000
--- a/res/drawable-xxhdpi/ic_dialog_alert_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_dialog_info_alpha.png b/res/drawable-xxhdpi/ic_dialog_info_alpha.png
deleted file mode 100644
index a81eeb9..0000000
--- a/res/drawable-xxhdpi/ic_dialog_info_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_hamburger_alpha.png b/res/drawable-xxhdpi/ic_hamburger_alpha.png
deleted file mode 100644
index 7dae60b..0000000
--- a/res/drawable-xxhdpi/ic_hamburger_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_compress_alpha.png b/res/drawable-xxhdpi/ic_menu_compress_alpha.png
deleted file mode 100644
index d6d60f6..0000000
--- a/res/drawable-xxhdpi/ic_menu_compress_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_copy_alpha.png b/res/drawable-xxhdpi/ic_menu_copy_alpha.png
deleted file mode 100644
index 074ea88..0000000
--- a/res/drawable-xxhdpi/ic_menu_copy_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_delete_alpha.png b/res/drawable-xxhdpi/ic_menu_delete_alpha.png
deleted file mode 100644
index 6d7cb81..0000000
--- a/res/drawable-xxhdpi/ic_menu_delete_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_extract_alpha.png b/res/drawable-xxhdpi/ic_menu_extract_alpha.png
deleted file mode 100644
index 7275663..0000000
--- a/res/drawable-xxhdpi/ic_menu_extract_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_new_folder_am_alpha.png b/res/drawable-xxhdpi/ic_menu_new_folder_am_alpha.png
deleted file mode 100644
index 5c4360a..0000000
--- a/res/drawable-xxhdpi/ic_menu_new_folder_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_search_alpha.png b/res/drawable-xxhdpi/ic_menu_search_alpha.png
deleted file mode 100644
index 3ae490e..0000000
--- a/res/drawable-xxhdpi/ic_menu_search_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_share_am_alpha.png b/res/drawable-xxhdpi/ic_menu_share_am_alpha.png
deleted file mode 100644
index 784933ad..0000000
--- a/res/drawable-xxhdpi/ic_menu_share_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_view_grid_alpha.png b/res/drawable-xxhdpi/ic_menu_view_grid_alpha.png
deleted file mode 100644
index 7560f62..0000000
--- a/res/drawable-xxhdpi/ic_menu_view_grid_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_view_list_alpha.png b/res/drawable-xxhdpi/ic_menu_view_list_alpha.png
deleted file mode 100644
index b9483c3..0000000
--- a/res/drawable-xxhdpi/ic_menu_view_list_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_breadcrumb_arrow_am_alpha.png b/res/drawable-xxxhdpi/ic_breadcrumb_arrow_am_alpha.png
deleted file mode 100644
index 6f2dc5b..0000000
--- a/res/drawable-xxxhdpi/ic_breadcrumb_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_cab_cancel_alpha.png b/res/drawable-xxxhdpi/ic_cab_cancel_alpha.png
deleted file mode 100644
index df42fee..0000000
--- a/res/drawable-xxxhdpi/ic_cab_cancel_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_dialog_alert_alpha.png b/res/drawable-xxxhdpi/ic_dialog_alert_alpha.png
deleted file mode 100644
index 3f4d539..0000000
--- a/res/drawable-xxxhdpi/ic_dialog_alert_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_dialog_info_alpha.png b/res/drawable-xxxhdpi/ic_dialog_info_alpha.png
deleted file mode 100644
index c8f86b9..0000000
--- a/res/drawable-xxxhdpi/ic_dialog_info_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_hamburger_alpha.png b/res/drawable-xxxhdpi/ic_hamburger_alpha.png
deleted file mode 100644
index 5c747ed..0000000
--- a/res/drawable-xxxhdpi/ic_hamburger_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_compress_alpha.png b/res/drawable-xxxhdpi/ic_menu_compress_alpha.png
deleted file mode 100644
index b8c0376..0000000
--- a/res/drawable-xxxhdpi/ic_menu_compress_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_copy_alpha.png b/res/drawable-xxxhdpi/ic_menu_copy_alpha.png
deleted file mode 100644
index 1f6af72..0000000
--- a/res/drawable-xxxhdpi/ic_menu_copy_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_delete_alpha.png b/res/drawable-xxxhdpi/ic_menu_delete_alpha.png
deleted file mode 100644
index f2b75c3..0000000
--- a/res/drawable-xxxhdpi/ic_menu_delete_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_extract_alpha.png b/res/drawable-xxxhdpi/ic_menu_extract_alpha.png
deleted file mode 100644
index 514d69b..0000000
--- a/res/drawable-xxxhdpi/ic_menu_extract_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_new_folder_am_alpha.png b/res/drawable-xxxhdpi/ic_menu_new_folder_am_alpha.png
deleted file mode 100644
index 073d853..0000000
--- a/res/drawable-xxxhdpi/ic_menu_new_folder_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_search_alpha.png b/res/drawable-xxxhdpi/ic_menu_search_alpha.png
deleted file mode 100644
index 21be572..0000000
--- a/res/drawable-xxxhdpi/ic_menu_search_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_share_am_alpha.png b/res/drawable-xxxhdpi/ic_menu_share_am_alpha.png
deleted file mode 100644
index 5a8544c..0000000
--- a/res/drawable-xxxhdpi/ic_menu_share_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_view_grid_alpha.png b/res/drawable-xxxhdpi/ic_menu_view_grid_alpha.png
deleted file mode 100644
index 5d1e8d9..0000000
--- a/res/drawable-xxxhdpi/ic_menu_view_grid_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_menu_view_list_alpha.png b/res/drawable-xxxhdpi/ic_menu_view_list_alpha.png
deleted file mode 100644
index 7c1506b..0000000
--- a/res/drawable-xxxhdpi/ic_menu_view_list_alpha.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/bottom_bar_positive_button_background.xml b/res/drawable/bottom_bar_positive_button_background.xml
deleted file mode 100644
index 037d5eb..0000000
--- a/res/drawable/bottom_bar_positive_button_background.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <corners android:radius="2dp" />
-    <solid android:color="@color/primary" />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/text_cursor.xml b/res/drawable/bottom_sheet_dialog_background.xml
similarity index 66%
copy from res/drawable/text_cursor.xml
copy to res/drawable/bottom_sheet_dialog_background.xml
index 1884749..703667a 100644
--- a/res/drawable/text_cursor.xml
+++ b/res/drawable/bottom_sheet_dialog_background.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,8 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle" >
-    <size android:width="1dp" />
-    <solid android:color="@color/text_cursor"/>
-</shape>
\ No newline at end of file
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <solid android:color="?android:attr/colorBackground" />
+
+    <corners android:topLeftRadius="@dimen/grid_item_radius"
+             android:topRightRadius="@dimen/grid_item_radius"
+             android:bottomLeftRadius="0dp"
+             android:bottomRightRadius="0dp"/>
+
+</shape>
diff --git a/res/drawable/breadcrumb_item_background.xml b/res/drawable/breadcrumb_item_background.xml
index c4bc77b..410e8ed 100644
--- a/res/drawable/breadcrumb_item_background.xml
+++ b/res/drawable/breadcrumb_item_background.xml
@@ -16,7 +16,7 @@
 
 <ripple
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res/com.android.documentsui"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:color="?attr/colorControlHighlight">
     <item
         android:id="@android:id/mask"
diff --git a/res/drawable/text_cursor.xml b/res/drawable/circle_button_background.xml
similarity index 79%
rename from res/drawable/text_cursor.xml
rename to res/drawable/circle_button_background.xml
index 1884749..d5b3c50 100644
--- a/res/drawable/text_cursor.xml
+++ b/res/drawable/circle_button_background.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,8 +13,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle" >
-    <size android:width="1dp" />
-    <solid android:color="@color/text_cursor"/>
+       android:shape="oval">
+    <solid
+        android:color="#66000000"/>
 </shape>
\ No newline at end of file
diff --git a/res/drawable/fast_scroll_thumb_drawable.xml b/res/drawable/fast_scroll_thumb_drawable.xml
index 0a7bf61..e2beaec 100644
--- a/res/drawable/fast_scroll_thumb_drawable.xml
+++ b/res/drawable/fast_scroll_thumb_drawable.xml
@@ -17,13 +17,13 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true">
         <shape  android:shape="rectangle">
-            <solid android:color="@color/scroll_thumb_pressed" />
+            <solid android:color="?android:attr/colorControlNormal" />
             <size android:width="8dp" android:height="48dp" />
         </shape>
     </item>
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/scroll_thumb" />
+            <solid android:color="?android:attr/colorControlNormal" />
             <size android:width="8dp" android:height="48dp" />
         </shape>
     </item>
diff --git a/res/drawable/fast_scroll_track_drawable.xml b/res/drawable/fast_scroll_track_drawable.xml
index 63ce70e..d363f1a 100644
--- a/res/drawable/fast_scroll_track_drawable.xml
+++ b/res/drawable/fast_scroll_track_drawable.xml
@@ -16,6 +16,6 @@
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
-    <solid android:color="@color/scroll_track" />
+    <solid android:color="@android:color/transparent" />
     <size android:width="8dp" />
 </shape>
diff --git a/res/drawable/text_select_handle_left.xml b/res/drawable/generic_ripple_background.xml
similarity index 62%
copy from res/drawable/text_select_handle_left.xml
copy to res/drawable/generic_ripple_background.xml
index bf3a743..edf52c4 100644
--- a/res/drawable/text_select_handle_left.xml
+++ b/res/drawable/generic_ripple_background.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,6 +14,13 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-        android:src="@drawable/search_text_select_handle_left"
-        android:tint="@color/text_handle" />
\ No newline at end of file
+<ripple
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?android:attr/colorControlHighlight">
+    <item
+        android:id="@android:id/mask">
+        <shape android:shape="rectangle">
+            <solid android:color="@android:color/white"/>
+        </shape>
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/res/drawable/text_cursor.xml b/res/drawable/gradient_actionbar_background.xml
similarity index 72%
copy from res/drawable/text_cursor.xml
copy to res/drawable/gradient_actionbar_background.xml
index 1884749..da29c45 100644
--- a/res/drawable/text_cursor.xml
+++ b/res/drawable/gradient_actionbar_background.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,8 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle" >
-    <size android:width="1dp" />
-    <solid android:color="@color/text_cursor"/>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:startColor="@color/tool_bar_gradient_max"
+        android:endColor="@android:color/transparent"
+        android:angle="270"
+        android:type="linear" >
+    </gradient>
 </shape>
\ No newline at end of file
diff --git a/res/drawable/grid_item_background.xml b/res/drawable/grid_item_background.xml
index 76649f1..9c4e644 100644
--- a/res/drawable/grid_item_background.xml
+++ b/res/drawable/grid_item_background.xml
@@ -15,10 +15,13 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@color/item_doc_background_selected"
-          android:state_selected="true" />
-    <item android:drawable="@color/item_hover_color"
-          android:state_drag_hovered="true" />
-    <item android:drawable="@color/item_doc_background"
-          android:state_selected="false" />
+    <item android:state_selected="true">
+        <color android:color="?android:colorSecondary"/>
+    </item>
+    <item android:state_drag_hovered="true">
+        <color android:color="?android:strokeColor"/>
+    </item>
+    <item android:state_selected="false">
+        <color android:color="?android:colorBackground"/>
+    </item>
 </selector>
\ No newline at end of file
diff --git a/res/drawable/ic_action_clear.xml b/res/drawable/ic_action_clear.xml
index 35d6529..38588b9 100644
--- a/res/drawable/ic_action_clear.xml
+++ b/res/drawable/ic_action_clear.xml
@@ -17,8 +17,9 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal" >
   <path
-      android:fillColor="#FF737373"
+      android:fillColor="@android:color/white"
       android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_arrow_back.xml b/res/drawable/ic_arrow_back.xml
new file mode 100644
index 0000000..1a99930
--- /dev/null
+++ b/res/drawable/ic_arrow_back.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019, The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="?android:colorControlNormal"
+        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_arrow_upward.xml b/res/drawable/ic_arrow_upward.xml
index 875eca5..dab39f9 100644
--- a/res/drawable/ic_arrow_upward.xml
+++ b/res/drawable/ic_arrow_upward.xml
@@ -15,12 +15,14 @@
     limitations under the License.
   -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
 
     <path
-        android:fillColor="#000000"
-        android:pathData="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"/>
+        android:pathData="M0 0h24v24H0V0z" />
+    <path
+        android:fillColor="?android:textColorSecondary"
+        android:pathData="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z" />
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_breadcrumb_arrow.xml b/res/drawable/ic_breadcrumb_arrow.xml
index 76c0e1f..f13be0f 100644
--- a/res/drawable/ic_breadcrumb_arrow.xml
+++ b/res/drawable/ic_breadcrumb_arrow.xml
@@ -1,5 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_breadcrumb_arrow_am_alpha"
-    android:tint="?android:attr/colorControlNormal"
-    android:autoMirrored="true" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6 -6,-6z"/>
+</vector>
diff --git a/res/drawable/ic_cab_cancel.xml b/res/drawable/ic_cab_cancel.xml
index 629100c..1eae40e 100644
--- a/res/drawable/ic_cab_cancel.xml
+++ b/res/drawable/ic_cab_cancel.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_cab_cancel_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12 19,6.41z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_root_documents.xml b/res/drawable/ic_check.xml
similarity index 73%
copy from res/drawable/ic_root_documents.xml
copy to res/drawable/ic_check.xml
index afd886d..a6df08a 100644
--- a/res/drawable/ic_root_documents.xml
+++ b/res/drawable/ic_check.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2018 The Android Open Source Project
 
    Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -17,8 +17,9 @@
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorPrimary">
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M10 4H4c-1.1 0,-1.99.9,-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2,-.9 2,-2V8c0,-1.1,-.9,-2,-2,-2h-8l-2,-2z"/>
+        android:fillColor="@android:color/white"
+        android:pathData="vM9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
 </vector>
diff --git a/res/drawable/ic_check_circle.xml b/res/drawable/ic_check_circle.xml
index 62a4e34..13b45bd 100644
--- a/res/drawable/ic_check_circle.xml
+++ b/res/drawable/ic_check_circle.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="?android:attr/colorAccent"
+        android:fillColor="?android:attr/colorPrimary"
         android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10,-4.48 10,-10S17.52 2 12 2zm-2 15l-5,-5 1.41,-1.41L10 14.17l7.59,-7.59L19 8l-9 9z"/>
 </vector>
diff --git a/res/drawable/ic_dialog_alert.xml b/res/drawable/ic_dialog_alert.xml
index 5132df3..8066483 100644
--- a/res/drawable/ic_dialog_alert.xml
+++ b/res/drawable/ic_dialog_alert.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_dialog_alert_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_dialog_info.xml b/res/drawable/ic_dialog_info.xml
index a029cca..f159351 100644
--- a/res/drawable/ic_dialog_info.xml
+++ b/res/drawable/ic_dialog_info.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_dialog_info_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_doc_album.xml b/res/drawable/ic_doc_album.xml
deleted file mode 100644
index 1ce3f02..0000000
--- a/res/drawable/ic_doc_album.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF737373"
-        android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10,-4.48 10,-10S17.52 2 12 2zm0 14.5c-2.49 0,-4.5,-2.01,-4.5,-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5,-2.01 4.5,-4.5 4.5zm0,-5.5c-.55 0,-1 .45,-1 1s.45 1 1 1 1,-.45 1,-1,-.45,-1,-1,-1z"/>
-</vector>
diff --git a/res/drawable/ic_doc_audio.xml b/res/drawable/ic_doc_audio.xml
deleted file mode 100644
index 341a919..0000000
--- a/res/drawable/ic_doc_audio.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFDB4437"
-        android:pathData="M19 3H5c-1.1 0,-2 .9,-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2,-.9 2,-2V5c0,-1.1,-.9,-2,-2,-2zM7.2 18c-.66 0,-1.2,-.54,-1.2,-1.2V12c0,-3.31 2.69,-6 6,-6s6 2.69 6 6v4.8c0 .66,-.54 1.2,-1.2 1.2H14v-4h2v-2c0,-2.21,-1.79,-4,-4,-4s-4 1.79,-4 4v2h2v4H7.2z"/>
-</vector>
diff --git a/res/drawable/ic_doc_folder.xml b/res/drawable/ic_doc_folder.xml
deleted file mode 100644
index dcbce01..0000000
--- a/res/drawable/ic_doc_folder.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF737373"
-        android:pathData="M10 4H4c-1.1 0,-1.99.9,-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2,-.9 2,-2V8c0,-1.1,-.9,-2,-2,-2h-8l-2,-2z"/>
-</vector>
diff --git a/res/drawable/ic_doc_generic.xml b/res/drawable/ic_doc_generic.xml
deleted file mode 100644
index a4fd77a..0000000
--- a/res/drawable/ic_doc_generic.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF737373"
-        android:pathData="M6 2c-1.1 0,-1.99.9,-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2,-.9 2,-2V8l-6,-6H6zm7 7V3.5L18.5 9H13z"/>
-</vector>
diff --git a/res/drawable/ic_doc_image.xml b/res/drawable/ic_doc_image.xml
deleted file mode 100644
index 1262563..0000000
--- a/res/drawable/ic_doc_image.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFDB4437"
-        android:pathData="M21 19V5c0,-1.1,-.9,-2,-2,-2H5c-1.1 0,-2 .9,-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2,-.9 2,-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5,-4.5z"/>
-</vector>
diff --git a/res/drawable/ic_doc_text.xml b/res/drawable/ic_doc_text.xml
deleted file mode 100644
index 7fc04e8..0000000
--- a/res/drawable/ic_doc_text.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF737373"
-        android:pathData="M14 2H6c-1.1 0,-1.99.9,-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2,-.9 2,-2V8l-6,-6zm2 16H8v-2h8v2zm0,-4H8v-2h8v2zm-3,-5V3.5L18.5 9H13z"/>
-</vector>
diff --git a/res/drawable/ic_doc_video.xml b/res/drawable/ic_doc_video.xml
deleted file mode 100644
index 4944232..0000000
--- a/res/drawable/ic_doc_video.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFDB4437"
-        android:pathData="M18 4l2 4h-3l-2,-4h-2l2 4h-3l-2,-4H8l2 4H7L5 4H4c-1.1 0,-1.99.9,-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2,-.9 2,-2V4h-4z"/>
-</vector>
diff --git a/res/drawable/text_select_handle_left.xml b/res/drawable/ic_done.xml
similarity index 60%
copy from res/drawable/text_select_handle_left.xml
copy to res/drawable/ic_done.xml
index bf3a743..f8f66b6 100644
--- a/res/drawable/text_select_handle_left.xml
+++ b/res/drawable/ic_done.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,7 +13,12 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-        android:src="@drawable/search_text_select_handle_left"
-        android:tint="@color/text_handle" />
\ No newline at end of file
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="?android:colorPrimary"
+        android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
+</vector>
diff --git a/res/drawable/ic_eject.xml b/res/drawable/ic_eject.xml
index cbcd755..0e1b36f 100644
--- a/res/drawable/ic_eject.xml
+++ b/res/drawable/ic_eject.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF737373"
+        android:fillColor="#5F6368"
         android:pathData="M5 17h14v2H5zm7-12L5.33 15h13.34z"/>
-</vector>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_root_documents.xml b/res/drawable/ic_exit_to_app.xml
similarity index 73%
rename from res/drawable/ic_root_documents.xml
rename to res/drawable/ic_exit_to_app.xml
index afd886d..b597def 100644
--- a/res/drawable/ic_root_documents.xml
+++ b/res/drawable/ic_exit_to_app.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2015 The Android Open Source Project
+Copyright (C) 2018 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.
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M10 4H4c-1.1 0,-1.99.9,-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2,-.9 2,-2V8c0,-1.1,-.9,-2,-2,-2h-8l-2,-2z"/>
+        android:fillColor="#5F6368"
+        android:pathData="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/>
 </vector>
diff --git a/res/drawable/ic_hamburger.xml b/res/drawable/ic_hamburger.xml
index 7cda32e..bc27352 100644
--- a/res/drawable/ic_hamburger.xml
+++ b/res/drawable/ic_hamburger.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_hamburger_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M3,18h18v-2H3V18zM3,13h18v-2H3V13zM3,6v2h18V6H3z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_history.xml b/res/drawable/ic_history.xml
new file mode 100644
index 0000000..df0636d
--- /dev/null
+++ b/res/drawable/ic_history.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:textColorSecondary"
+        android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l4,3.99L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.25,2.52 0.77,-1.28 -3.52,-2.09L13.5,8z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_compress.xml b/res/drawable/ic_menu_compress.xml
index bee9465..cdb328e 100644
--- a/res/drawable/ic_menu_compress.xml
+++ b/res/drawable/ic_menu_compress.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_compress_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path
+    android:fillColor="?android:attr/colorControlNormal"
+    android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 -0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 -0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_copy.xml b/res/drawable/ic_menu_copy.xml
index e0abe07..9c391da 100644
--- a/res/drawable/ic_menu_copy.xml
+++ b/res/drawable/ic_menu_copy.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_copy_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM15,5L8,5c-1.1,0 -1.99,0.9 -1.99,2L6,21c0,1.1 0.89,2 1.99,2L19,23c1.1,0 2,-0.9 2,-2L21,11l-6,-6zM8,21L8,7h6v5h5v9L8,21z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_delete.xml b/res/drawable/ic_menu_delete.xml
index e52ed97..bfe3ed6 100644
--- a/res/drawable/ic_menu_delete.xml
+++ b/res/drawable/ic_menu_delete.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_delete_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_extract.xml b/res/drawable/ic_menu_extract.xml
index 8458e15..7770148 100644
--- a/res/drawable/ic_menu_extract.xml
+++ b/res/drawable/ic_menu_extract.xml
@@ -1,4 +1,28 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_extract_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <group>
+        <clip-path android:pathData="M0,0h24v24H0V0z M 0,0"/>
+        <path
+            android:fillColor="?android:attr/colorControlNormal"
+            android:pathData="M20.55 5.22l-1.39,-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0,-.88.21,-1.15.55L3.46 5.22C3.17 5.57 3 6.01 3 6.5V19c0 1.1.89 2 2 2h14c1.1 0 2,-.9 2,-2V6.5c0,-.49,-.17,-.93,-.45,-1.28zM12 9.5l5.5 5.5H14v2h-4v-2H6.5L12 9.5zM5.12 5l.82,-1h12l.93 1H5.12z"/>
+    </group>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_new_folder.xml b/res/drawable/ic_menu_new_folder.xml
deleted file mode 100644
index b105535..0000000
--- a/res/drawable/ic_menu_new_folder.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_new_folder_am_alpha"
-    android:tint="?android:attr/colorControlNormal"
-    android:autoMirrored="true" />
diff --git a/res/drawable/ic_menu_search.xml b/res/drawable/ic_menu_search.xml
index 33f548b..4d92eee 100644
--- a/res/drawable/ic_menu_search.xml
+++ b/res/drawable/ic_menu_search.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_search_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_share.xml b/res/drawable/ic_menu_share.xml
index d4a92c5..5ff5c86 100644
--- a/res/drawable/ic_menu_share.xml
+++ b/res/drawable/ic_menu_share.xml
@@ -1,5 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_share_am_alpha"
-    android:tint="?android:attr/colorControlNormal"
-    android:autoMirrored="true" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_view_grid.xml b/res/drawable/ic_menu_view_grid.xml
index dc09a0c..4279bfe 100644
--- a/res/drawable/ic_menu_view_grid.xml
+++ b/res/drawable/ic_menu_view_grid.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_view_grid_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M4,11h5L9,5L4,5v6zM4,18h5v-6L4,12v6zM10,18h5v-6h-5v6zM16,18h5v-6h-5v6zM10,11h5L15,5h-5v6zM16,5v6h5L21,5h-5z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_menu_view_list.xml b/res/drawable/ic_menu_view_list.xml
index 23c5777..7428c55 100644
--- a/res/drawable/ic_menu_view_list.xml
+++ b/res/drawable/ic_menu_view_list.xml
@@ -1,4 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_menu_view_list_alpha"
-    android:tint="?android:attr/colorControlNormal" />
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M4,14h2c0.55,0 1,-0.45 1,-1v-2c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v2C3,13.55 3.45,14 4,14zM4,19h2c0.55,0 1,-0.45 1,-1v-2c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v2C3,18.55 3.45,19 4,19zM4,9h2c0.55,0 1,-0.45 1,-1V6c0,-0.55 -0.45,-1 -1,-1H4C3.45,5 3,5.45 3,6v2C3,8.55 3.45,9 4,9zM9,14h10c0.55,0 1,-0.45 1,-1v-2c0,-0.55 -0.45,-1 -1,-1H9c-0.55,0 -1,0.45 -1,1v2C8,13.55 8.45,14 9,14zM9,19h10c0.55,0 1,-0.45 1,-1v-2c0,-0.55 -0.45,-1 -1,-1H9c-0.55,0 -1,0.45 -1,1v2C8,18.55 8.45,19 9,19zM8,6v2c0,0.55 0.45,1 1,1h10c0.55,0 1,-0.45 1,-1V6c0,-0.55 -0.45,-1 -1,-1H9C8.45,5 8,5.45 8,6z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_root_download.xml b/res/drawable/ic_root_download.xml
index c09be05..56c7ea7 100644
--- a/res/drawable/ic_root_download.xml
+++ b/res/drawable/ic_root_download.xml
@@ -20,6 +20,6 @@
         android:viewportHeight="24"
         android:viewportWidth="24">
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="#5F6368"
         android:pathData="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" />
 </vector>
diff --git a/res/drawable/ic_root_recent.xml b/res/drawable/ic_root_recent.xml
index 84599fd..cbc3340 100644
--- a/res/drawable/ic_root_recent.xml
+++ b/res/drawable/ic_root_recent.xml
@@ -21,11 +21,11 @@
         android:viewportHeight="24">
 
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="#5F6368"
         android:pathData="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2
 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />
 
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="#5F6368"
         android:pathData="M12.5 7H11v6l5.25 3.15 .75 -1.23-4.5-2.67z" />
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_root_smartphone.xml b/res/drawable/ic_root_smartphone.xml
index 3021b16..ad647ff 100644
--- a/res/drawable/ic_root_smartphone.xml
+++ b/res/drawable/ic_root_smartphone.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="#5F6368"
         android:pathData="M17 1.01L7 1c-1.1 0,-2 .9,-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2,-.9 2,-2V3c0,-1.1,-.9,-1.99,-2,-1.99zM17 19H7V5h10v14z"/>
 </vector>
diff --git a/res/drawable/ic_sd_storage.xml b/res/drawable/ic_sd_storage.xml
index 5aeebbb..8d9e4a6 100644
--- a/res/drawable/ic_sd_storage.xml
+++ b/res/drawable/ic_sd_storage.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="#5F6368"
         android:pathData="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2,-.9 2,-2V4c0,-1.1,-.9,-2,-2,-2zm-6 6h-2V4h2v4zm3 0h-2V4h2v4zm3 0h-2V4h2v4z"/>
 </vector>
diff --git a/res/drawable/ic_subdirectory_arrow.xml b/res/drawable/ic_subdirectory_arrow.xml
index 0f34ba4..35f5ca5 100644
--- a/res/drawable/ic_subdirectory_arrow.xml
+++ b/res/drawable/ic_subdirectory_arrow.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="?android:attr/colorControlNormal"
+        android:fillColor="?android:textColorSecondary"
         android:pathData="M19 15l-6 6,-1.42,-1.42L15.17 16H4V4h2v10h9.17l-3.59,-3.58L13 9l6 6z"/>
 </vector>
diff --git a/res/drawable/ic_usb_storage.xml b/res/drawable/ic_usb_storage.xml
index 2a8d024..60cb6c2 100644
--- a/res/drawable/ic_usb_storage.xml
+++ b/res/drawable/ic_usb_storage.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="?android:textColorSecondary"
         android:pathData="M15 7v4h1v2h-3V5h2l-3,-4,-3 4h2v8H8v-2.07c.7,-.37 1.2,-1.08 1.2,-1.93 0,-1.21,-.99,-2.2,-2.2,-2.2,-1.21 0,-2.2.99,-2.2 2.2 0 .85.5 1.56 1.2 1.93V13c0 1.11.89 2 2 2h3v3.05c-.71.37,-1.2 1.1,-1.2 1.95 0 1.22.99 2.2 2.2 2.2 1.21 0 2.2,-.98 2.2,-2.2 0,-.85,-.49,-1.58,-1.2,-1.95V15h3c1.11 0 2,-.89 2,-2v-2h1V7h-4z"/>
 </vector>
diff --git a/res/drawable/ic_user_profile.xml b/res/drawable/ic_user_profile.xml
new file mode 100644
index 0000000..42e06a5
--- /dev/null
+++ b/res/drawable/ic_user_profile.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm6.36 14.83c-1.43-1.74-4.9-2.33-6.36-2.33s-4.93.59-6.36 2.33C4.62 15.49 4 13.82 4 12c0-4.41 3.59-8 8-8s8 3.59 8 8c0 1.82-.62 3.49-1.64 4.83zM12 6c-1.94 0-3.5 1.56-3.5 3.5S10.06 13 12 13s3.5-1.56 3.5-3.5S13.94 6 12 6z"
+        android:fillColor="#4285F4"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_zoom_out.xml b/res/drawable/ic_zoom_out.xml
new file mode 100644
index 0000000..295054a
--- /dev/null
+++ b/res/drawable/ic_zoom_out.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M15,3l2.3,2.3 -2.89,2.87 1.42,1.42L18.7,6.7 21,9L21,3zM3,9l2.3,-2.3 2.87,2.89 1.42,-1.42L6.7,5.3 9,3L3,3zM9,21l-2.3,-2.3 2.89,-2.87 -1.42,-1.42L5.3,17.3 3,15v6zM21,15l-2.3,2.3 -2.87,-2.89 -1.42,1.42 2.89,2.87L15,21h6z"/>
+</vector>
diff --git a/res/drawable/inspector_separator.xml b/res/drawable/inspector_separator.xml
index 6a35283..cbb494a 100644
--- a/res/drawable/inspector_separator.xml
+++ b/res/drawable/inspector_separator.xml
@@ -16,8 +16,9 @@
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetTop="10dp"
     android:insetBottom="10dp" >
-    <shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <shape xmlns:android="http://schemas.android.com/apk/res/android"
+           android:tint="?android:attr/colorForeground">
         <size android:height="1dp"/>
-        <solid android:color="@color/inspector_section_divider"/>
+        <solid android:color="#1f000000"/>
     </shape>
 </inset>
\ No newline at end of file
diff --git a/res/drawable/text_cursor.xml b/res/drawable/item_doc_grid_border_rounded.xml
similarity index 69%
copy from res/drawable/text_cursor.xml
copy to res/drawable/item_doc_grid_border_rounded.xml
index 1884749..e6ffbca 100644
--- a/res/drawable/text_cursor.xml
+++ b/res/drawable/item_doc_grid_border_rounded.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
@@ -13,8 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle" >
-    <size android:width="1dp" />
-    <solid android:color="@color/text_cursor"/>
-</shape>
\ No newline at end of file
+       android:shape="rectangle">
+    <stroke
+        android:width="2dp"
+        android:color="@color/item_doc_grid_border"/>
+    <corners android:radius="@dimen/grid_item_radius"/>
+</shape>
diff --git a/res/color/item_title.xml b/res/drawable/list_checker.xml
similarity index 74%
rename from res/color/item_title.xml
rename to res/drawable/list_checker.xml
index d1760d0..d0d3a1d 100644
--- a/res/color/item_title.xml
+++ b/res/drawable/list_checker.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,12 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_enabled="true"
-        android:color="@color/item_doc_title" />
+        android:state_checked="true"
+        android:drawable="@drawable/ic_done"/>
     <item
-        android:state_enabled="false"
-        android:color="@color/item_doc_title_disabled"/>
-</selector>
+        android:drawable="@android:color/transparent"/>
+</selector>
\ No newline at end of file
diff --git a/res/drawable/list_item_background.xml b/res/drawable/list_item_background.xml
index 03f6c54..afbeecd 100644
--- a/res/drawable/list_item_background.xml
+++ b/res/drawable/list_item_background.xml
@@ -15,13 +15,17 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@color/item_doc_background_selected"
-          android:state_focused="true" />
-    <item android:drawable="@color/item_doc_background_selected"
-          android:state_selected="true" />
-    <item android:drawable="@color/item_hover_color"
-          android:state_drag_hovered="true" />
-    <item android:drawable="@color/item_doc_background"
-          android:state_selected="false"
-          android:state_focused="false" />
+    <item android:state_focused="true" >
+        <color android:color="?android:colorSecondary"/>
+    </item>
+    <item android:state_selected="true">
+        <color android:color="?android:colorSecondary"/>
+    </item>
+    <item android:state_drag_hovered="true">
+        <color android:color="?android:strokeColor"/>
+    </item>
+    <item android:state_selected="false"
+          android:state_focused="false">
+        <color android:color="@color/app_background_color"/>
+    </item>
 </selector>
\ No newline at end of file
diff --git a/res/drawable/menu_dropdown_panel.xml b/res/drawable/menu_dropdown_panel.xml
new file mode 100644
index 0000000..f750f0d
--- /dev/null
+++ b/res/drawable/menu_dropdown_panel.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+    <!-- Panel shadow -->
+    <item>
+        <shape
+            xmlns:android="http://schemas.android.com/apk/res/android"
+            android:shape="rectangle"
+            android:tint="?android:attr/colorBackgroundFloating">
+            <stroke android:width="2dp" android:color="#3C4043" />
+            <solid android:color="#5F6368" />
+            <corners
+                android:topRightRadius="@dimen/material_round_radius"
+                android:topLeftRadius="@dimen/material_round_radius"
+                android:bottomRightRadius="@dimen/material_round_radius"
+                android:bottomLeftRadius="@dimen/material_round_radius"/>
+        </shape>
+    </item>
+    <!-- Panel surface -->
+    <item android:bottom="2dp">
+        <shape
+            xmlns:android="http://schemas.android.com/apk/res/android"
+            android:shape="rectangle"
+            android:tint="?android:attr/colorBackgroundFloating">
+            <corners
+                android:topRightRadius="@dimen/material_round_radius"
+                android:topLeftRadius="@dimen/material_round_radius"
+                android:bottomRightRadius="@dimen/material_round_radius"
+                android:bottomLeftRadius="@dimen/material_round_radius"/>
+        </shape>
+    </item>
+</layer-list>
diff --git a/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml b/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
index 070b9a1..a6668bc 100644
--- a/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
+++ b/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
@@ -21,8 +21,8 @@
     android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal_trimmed" >
     <target
         android:name="rect2_grp"
-        android:animation="@*android:anim/progress_indeterminate_horizontal_rect2" />
+        android:animation="@anim/progress_indeterminate_horizontal_rect2" />
     <target
         android:name="rect1_grp"
-        android:animation="@*android:anim/progress_indeterminate_horizontal_rect1" />
+        android:animation="@anim/progress_indeterminate_horizontal_rect1" />
 </animated-vector>
diff --git a/res/drawable/root_item_background.xml b/res/drawable/root_item_background.xml
index cc0bca6..6eca486 100644
--- a/res/drawable/root_item_background.xml
+++ b/res/drawable/root_item_background.xml
@@ -16,20 +16,28 @@
 
 <ripple
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res/com.android.documentsui"
-    android:color="?attr/colorControlHighlight">
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:color="?android:attr/colorControlHighlight">
     <item
         android:id="@android:id/mask"
-        android:drawable="@android:color/white"/>
+        android:drawable="@drawable/root_list_selector"/>
+
+    <item>
+        <selector>
+            <item app:state_highlighted="true">
+                <color android:color="?android:attr/colorControlHighlight"/>
+            </item>
+            <item
+                app:state_highlighted="false"
+                android:drawable="@android:color/transparent"/>
+        </selector>
+    </item>
 
     <item>
         <selector>
             <item
-                app:state_highlighted="true"
-                android:drawable="@color/item_hover_color"/>
-            <item
-                app:state_highlighted="false"
-                android:drawable="@android:color/transparent"/>
+                android:state_activated="true"
+                android:drawable="@drawable/root_list_selector"/>
         </selector>
     </item>
 </ripple>
\ No newline at end of file
diff --git a/res/drawable/root_list_selector.xml b/res/drawable/root_list_selector.xml
index b913267..911c2ed 100644
--- a/res/drawable/root_list_selector.xml
+++ b/res/drawable/root_list_selector.xml
@@ -14,12 +14,17 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-  <item
-    android:state_focused="true"
-    android:state_pressed="false">
-      <color android:color="@color/root_focus_color" />
-  </item>
-
-</selector>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:inset="8dp">
+    <shape
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+        <corners
+            android:topLeftRadius="2dp"
+            android:topRightRadius="2dp"
+            android:bottomLeftRadius="2dp"
+            android:bottomRightRadius="2dp"/>
+        <solid
+            android:color="?android:attr/colorSecondary"/>
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/res/drawable/roots_list_border.xml b/res/drawable/roots_list_border.xml
deleted file mode 100644
index 6ef6082..0000000
--- a/res/drawable/roots_list_border.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-       android:insetTop="-1dp"
-       android:insetBottom="-1dp"
-       android:insetLeft="-1dp">
-    <shape android:shape="rectangle">
-        <stroke
-            android:width="1dp"
-            android:color="@color/drawer_border" />
-    </shape>
-</inset>
\ No newline at end of file
diff --git a/res/drawable/search_bar_background.xml b/res/drawable/search_bar_background.xml
new file mode 100644
index 0000000..ab657c3
--- /dev/null
+++ b/res/drawable/search_bar_background.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape android:shape="rectangle">
+            <solid android:color="@android:color/transparent"/>
+        </shape>
+    </item>
+    <item
+        android:start="@dimen/search_bar_background_margin_start"
+        android:end="@dimen/search_bar_background_margin_end">
+        <shape android:shape="rectangle">
+            <solid android:color="?android:attr/colorBackgroundFloating"/>
+            <corners android:radius="@dimen/search_bar_radius"/>
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/text_select_handle_middle.xml b/res/drawable/text_select_handle_middle.xml
deleted file mode 100644
index a8706bc..0000000
--- a/res/drawable/text_select_handle_middle.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-        android:src="@drawable/search_text_select_handle_middle"
-        android:tint="@color/text_handle" />
\ No newline at end of file
diff --git a/res/drawable/text_select_handle_right.xml b/res/drawable/text_select_handle_right.xml
deleted file mode 100644
index 710b4ac..0000000
--- a/res/drawable/text_select_handle_right.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-        android:src="@drawable/search_text_select_handle_right"
-        android:tint="@color/text_handle" />
\ No newline at end of file
diff --git a/res/drawable/text_select_handle_left.xml b/res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml
similarity index 64%
copy from res/drawable/text_select_handle_left.xml
copy to res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml
index bf3a743..39efe84 100644
--- a/res/drawable/text_select_handle_left.xml
+++ b/res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,6 +13,5 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-        android:src="@drawable/search_text_select_handle_left"
-        android:tint="@color/text_handle" />
\ No newline at end of file
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0 0 L 0.3665 0 C 0.47252618112021,0.062409910275 0.61541608570164,0.5 0.68325,0.5 C 0.75475061236836,0.5 0.75725829093844,0.814510098964 1.0,1.0" />
diff --git a/res/drawable/text_select_handle_left.xml b/res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml
similarity index 64%
rename from res/drawable/text_select_handle_left.xml
rename to res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml
index bf3a743..46e0777 100644
--- a/res/drawable/text_select_handle_left.xml
+++ b/res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,6 +14,5 @@
      limitations under the License.
 -->
 
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-        android:src="@drawable/search_text_select_handle_left"
-        android:tint="@color/text_handle" />
\ No newline at end of file
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 L 0.2 0 C 0.3958333333336,0.0 0.474845090492,0.206797621729 0.5916666666664,0.417082932942 C 0.7151610251224,0.639379624869 0.81625,0.974556908664 1.0,1.0 " />
diff --git a/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml b/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml
new file mode 100644
index 0000000..34ebe07
--- /dev/null
+++ b/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 C 0.06834272400867,0.01992566661414 0.19220331656133,0.15855429260523 0.33333333333333,0.34926160892842 C 0.38410433133433,0.41477913453861 0.54945792615267,0.68136029463551 0.66666666666667,0.68279962777002 C 0.752586273196,0.68179620963216 0.737253971954,0.878896194318 1,1" />
diff --git a/res/color/item_title.xml b/res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml
similarity index 61%
copy from res/color/item_title.xml
copy to res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml
index d1760d0..d740e01 100644
--- a/res/color/item_title.xml
+++ b/res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,11 +14,5 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:state_enabled="true"
-        android:color="@color/item_doc_title" />
-    <item
-        android:state_enabled="false"
-        android:color="@color/item_doc_title_disabled"/>
-</selector>
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 C 0.0375,0.0 0.128764607715,0.0895380946618 0.25,0.218553507947 C 0.322410320025,0.295610602487 0.436666666667,0.417591408114 0.483333333333,0.489826169306 C 0.69,0.80972296795 0.793333333333,0.950016125212 1.0,1.0 " />
diff --git a/res/layout-sw720dp-land/column_headers.xml b/res/layout-sw720dp/column_headers.xml
similarity index 93%
rename from res/layout-sw720dp-land/column_headers.xml
rename to res/layout-sw720dp/column_headers.xml
index d5bcb76..60be5dc 100644
--- a/res/layout-sw720dp-land/column_headers.xml
+++ b/res/layout-sw720dp/column_headers.xml
@@ -31,7 +31,7 @@
         android:gravity="center_vertical"
         android:minHeight="@dimen/list_item_height"
         android:paddingStart="@dimen/list_item_padding"
-        android:paddingEnd="@dimen/list_item_padding"
+        android:paddingEnd="@dimen/list_item_width"
         android:orientation="horizontal">
         <!-- Placeholder for icon -->
         <View
@@ -52,7 +52,7 @@
                 android:id="@android:id/title"
                 android:layout_width="0dp"
                 android:layout_height="match_parent"
-                android:layout_weight="0.375"
+                android:layout_weight="0.4"
                 android:layout_marginEnd="12dp"
                 android:focusable="true"
                 android:gravity="center_vertical"
@@ -66,8 +66,8 @@
                 android:id="@android:id/summary"
                 android:layout_width="0dp"
                 android:layout_height="match_parent"
-                android:layout_weight="0.25"
-                android:layout_marginEnd="12dp"
+                android:layout_weight="0"
+                android:layout_marginEnd="0dp"
                 android:focusable="true"
                 android:gravity="center_vertical"
                 android:orientation="horizontal"
@@ -80,7 +80,7 @@
                 android:id="@+id/file_type"
                 android:layout_width="0dp"
                 android:layout_height="match_parent"
-                android:layout_weight="0.125"
+                android:layout_weight="0.2"
                 android:layout_marginEnd="12dp"
                 android:focusable="true"
                 android:gravity="center_vertical"
@@ -94,7 +94,7 @@
                 android:id="@+id/size"
                 android:layout_width="0dp"
                 android:layout_height="match_parent"
-                android:layout_weight="0.125"
+                android:layout_weight="0.2"
                 android:layout_marginEnd="12dp"
                 android:focusable="true"
                 android:gravity="center_vertical"
@@ -108,7 +108,7 @@
                 android:id="@+id/date"
                 android:layout_width="0dp"
                 android:layout_height="match_parent"
-                android:layout_weight="0.125"
+                android:layout_weight="0.2"
                 android:layout_marginEnd="12dp"
                 android:focusable="true"
                 android:gravity="center_vertical"
diff --git a/res/layout-sw720dp/directory_app_bar.xml b/res/layout-sw720dp/directory_app_bar.xml
new file mode 100644
index 0000000..4bb6361
--- /dev/null
+++ b/res/layout-sw720dp/directory_app_bar.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<com.google.android.material.appbar.AppBarLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/app_bar"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/colorBackground">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:layout_margin="@dimen/search_bar_margin"
+        android:background="?android:attr/colorBackground"
+        android:theme="?actionBarTheme"
+        android:popupTheme="?actionBarPopupTheme"
+        android:elevation="3dp"
+        app:titleTextAppearance="@style/ToolbarTitle"
+        app:layout_collapseMode="pin">
+
+        <TextView
+            android:id="@+id/searchbar_title"
+            android:layout_width="match_parent"
+            android:layout_height="?android:attr/actionBarSize"
+            android:layout_marginStart="@dimen/search_bar_text_margin_start"
+            android:layout_marginEnd="@dimen/search_bar_text_margin_end"
+            android:paddingStart="@dimen/search_bar_icon_padding"
+            android:gravity="center_vertical"
+            android:text="@string/search_bar_hint"
+            android:textAppearance="@style/SearchBarTitle"
+            android:drawableStart="@drawable/ic_menu_search"
+            android:drawablePadding="@dimen/search_bar_icon_padding"/>
+
+        <com.android.documentsui.DropdownBreadcrumb
+            android:id="@+id/dropdown_breadcrumb"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_marginStart="4dp"
+            android:popupTheme="?actionBarPopupTheme"
+            android:background="@android:color/transparent"
+            android:overlapAnchor="true"/>
+
+    </androidx.appcompat.widget.Toolbar>
+
+    <include layout="@layout/directory_header"/>
+
+</com.google.android.material.appbar.AppBarLayout>
\ No newline at end of file
diff --git a/res/layout-sw720dp-land/item_doc_list.xml b/res/layout-sw720dp/item_doc_list.xml
similarity index 74%
rename from res/layout-sw720dp-land/item_doc_list.xml
rename to res/layout-sw720dp/item_doc_list.xml
index bc2fc4c..d269154 100644
--- a/res/layout-sw720dp-land/item_doc_list.xml
+++ b/res/layout-sw720dp/item_doc_list.xml
@@ -18,7 +18,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@drawable/list_item_background"
+    android:background="?android:attr/selectableItemBackground"
     android:focusable="true"
     android:orientation="horizontal" >
 
@@ -28,17 +28,17 @@
         android:baselineAligned="false"
         android:gravity="center_vertical"
         android:minHeight="@dimen/list_item_height"
-        android:orientation="horizontal"
-        android:paddingEnd="@dimen/list_item_padding"
-        android:paddingStart="@dimen/list_item_padding" >
+        android:orientation="horizontal" >
 
         <FrameLayout
             android:id="@android:id/icon"
             android:pointerIcon="hand"
-            android:layout_width="@dimen/list_item_thumbnail_size"
-            android:layout_height="@dimen/list_item_thumbnail_size"
-            android:layout_marginEnd="16dp"
-            android:layout_marginStart="0dp" >
+            android:layout_width="@dimen/list_item_width"
+            android:layout_height="@dimen/list_item_height"
+            android:paddingBottom="@dimen/list_item_icon_padding"
+            android:paddingTop="@dimen/list_item_icon_padding"
+            android:paddingEnd="16dp"
+            android:paddingStart="@dimen/list_item_padding" >
 
             <ImageView
                 android:id="@+id/icon_mime"
@@ -81,7 +81,7 @@
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_marginEnd="12dp"
-                android:layout_weight="0.375"
+                android:layout_weight="0.4"
                 android:ellipsize="middle"
                 android:singleLine="true"
                 android:textAlignment="viewStart"
@@ -89,23 +89,11 @@
                 android:textColor="?android:attr/textColorPrimary" />
 
             <TextView
-                android:id="@android:id/summary"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="12dp"
-                android:layout_weight="0.25"
-                android:ellipsize="end"
-                android:singleLine="true"
-                android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Body1"
-                android:textColor="?android:attr/textColorSecondary" />
-
-            <TextView
                 android:id="@+id/file_type"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_marginEnd="12dp"
-                android:layout_weight="0.125"
+                android:layout_weight="0.2"
                 android:ellipsize="end"
                 android:singleLine="true"
                 android:textAlignment="viewStart"
@@ -117,7 +105,7 @@
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_marginEnd="12dp"
-                android:layout_weight="0.125"
+                android:layout_weight="0.2"
                 android:ellipsize="end"
                 android:minWidth="70dp"
                 android:singleLine="true"
@@ -130,7 +118,7 @@
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:layout_marginEnd="12dp"
-                android:layout_weight="0.125"
+                android:layout_weight="0.2"
                 android:ellipsize="end"
                 android:minWidth="70dp"
                 android:singleLine="true"
@@ -138,6 +126,34 @@
                 android:textAppearance="@android:style/TextAppearance.Material.Body1"
                 android:textColor="?android:attr/textColorSecondary" />
         </LinearLayout>
+
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+
+            <FrameLayout
+                android:id="@+id/preview_icon"
+                android:layout_width="@dimen/list_item_width"
+                android:layout_height="@dimen/list_item_height"
+                android:padding="@dimen/list_item_icon_padding"
+                android:focusable="true">
+
+                <ImageView
+                    android:layout_width="@dimen/check_icon_size"
+                    android:layout_height="@dimen/check_icon_size"
+                    android:layout_gravity="center"
+                    android:scaleType="fitCenter"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:src="@drawable/ic_zoom_out"/>
+
+            </FrameLayout>
+
+            <android.widget.Space
+                android:layout_width="@dimen/list_item_width"
+                android:layout_height="@dimen/list_item_height"/>
+
+        </FrameLayout>
+
     </LinearLayout>
 
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-sw720dp-land/shared_cell_content.xml b/res/layout-sw720dp/shared_cell_content.xml
similarity index 99%
rename from res/layout-sw720dp-land/shared_cell_content.xml
rename to res/layout-sw720dp/shared_cell_content.xml
index 387fe4c..2a811f9 100644
--- a/res/layout-sw720dp-land/shared_cell_content.xml
+++ b/res/layout-sw720dp/shared_cell_content.xml
@@ -34,4 +34,4 @@
         android:visibility="gone"
         android:src="@drawable/ic_sort_arrow"
         android:contentDescription="@null"/>
-</merge>
+</merge>
\ No newline at end of file
diff --git a/res/layout/apps_item.xml b/res/layout/apps_item.xml
new file mode 100644
index 0000000..91d94a3
--- /dev/null
+++ b/res/layout/apps_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="0dp"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:minWidth="@dimen/apps_row_item_width"
+    android:paddingBottom="@dimen/apps_row_exit_icon_margin_bottom"
+    android:orientation="vertical"
+    android:background="@drawable/generic_ripple_background"
+    android:gravity="center_horizontal">
+
+    <ImageView
+        android:id="@+id/app_icon"
+        android:layout_width="@dimen/apps_row_app_icon_size"
+        android:layout_height="@dimen/apps_row_app_icon_size"
+        android:layout_marginTop="@dimen/apps_row_app_icon_margin_top"
+        android:layout_marginBottom="@dimen/apps_row_app_icon_margin_bottom"
+        android:layout_marginStart="@dimen/apps_row_app_icon_margin_horizontal"
+        android:layout_marginEnd="@dimen/apps_row_app_icon_margin_horizontal"/>
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/apps_row_item_text_margin_horizontal"
+        android:layout_marginEnd="@dimen/apps_row_item_text_margin_horizontal"
+        android:textAppearance="@style/AppsItemText"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:gravity="center"/>
+
+    <ImageView
+        android:id="@+id/exit_icon"
+        android:layout_width="@dimen/apps_row_exit_icon_size"
+        android:layout_height="@dimen/apps_row_exit_icon_size"
+        android:layout_marginTop="@dimen/apps_row_exit_icon_margin_top"
+        android:scaleType="centerInside"
+        android:src="@drawable/ic_exit_to_app"
+        android:tint="?android:textColorSecondary"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/apps_row.xml b/res/layout/apps_row.xml
new file mode 100644
index 0000000..0b8504a
--- /dev/null
+++ b/res/layout/apps_row.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/apps_row"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minHeight="@dimen/apps_row_title_height"
+        android:paddingStart="@dimen/apps_row_title_padding_start"
+        android:textAppearance="@style/SortTitle"
+        android:text="@string/apps_row_title"
+        android:textAllCaps="true"
+        android:gravity="center"/>
+
+    <HorizontalScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:fillViewport="true"
+        android:scrollbars="none">
+        <LinearLayout
+            android:id="@+id/apps_group"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"/>
+    </HorizontalScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_delete_confirmation.xml b/res/layout/dialog_delete_confirmation.xml
index cd4d537..501736c 100644
--- a/res/layout/dialog_delete_confirmation.xml
+++ b/res/layout/dialog_delete_confirmation.xml
@@ -21,6 +21,5 @@
     android:paddingTop="24dp"
     android:paddingStart="24dp"
     android:paddingEnd="24dp"
-    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-    android:textColor="@color/dialog_title">
+    android:textAppearance="@android:style/TextAppearance.Material.Subhead">
 </TextView>
diff --git a/res/layout/dialog_file_name.xml b/res/layout/dialog_file_name.xml
index 6f8f9cf..0ebd936 100644
--- a/res/layout/dialog_file_name.xml
+++ b/res/layout/dialog_file_name.xml
@@ -17,18 +17,25 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:fitsSystemWindows="true"
-    android:padding="?android:attr/listPreferredItemPaddingEnd">
-    <android.support.design.widget.TextInputLayout
-        android:id="@+id/rename_input_wrapper"
+    android:fitsSystemWindows="true">
+
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/input_wrapper"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_centerInParent="true" >
-        <EditText
+        android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
+        android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:layout_marginTop="@dimen/dialog_content_padding_top"
+        android:layout_marginBottom="@dimen/dialog_content_padding_bottom"
+        android:layout_centerInParent="true"
+        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
+
+        <com.google.android.material.textfield.TextInputEditText
             android:id="@android:id/text1"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:inputType="text"/>
-    </android.support.design.widget.TextInputLayout>
+            android:inputType="textCapSentences"/>
+
+    </com.google.android.material.textfield.TextInputLayout>
 </FrameLayout>
diff --git a/res/layout/dialog_open_scoped_directory.xml b/res/layout/dialog_open_scoped_directory.xml
deleted file mode 100644
index bfb0271..0000000
--- a/res/layout/dialog_open_scoped_directory.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:theme="@style/Theme.AppCompat.Light.Dialog.Alert"
-    android:orientation="vertical"
-    android:paddingEnd="24dp"
-    android:paddingStart="24dp" >
-
-    <TextView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/message"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingEnd="24dp"
-        android:paddingStart="32dp"
-        android:paddingTop="24dp">
-    </TextView>
-
-    <CheckBox
-        android:id="@+id/do_not_ask_checkbox"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="16dip"
-        android:text="@string/never_ask_again"
-        android:textColor="?android:attr/textColorSecondary"
-        android:visibility="gone" />
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_sorting.xml b/res/layout/dialog_sorting.xml
new file mode 100644
index 0000000..d8cb736
--- /dev/null
+++ b/res/layout/dialog_sorting.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingTop="?android:attr/listPreferredItemPaddingStart"
+        android:paddingBottom="?android:attr/listPreferredItemPaddingStart"
+        android:textAllCaps="true"
+        android:text="@string/sort_dimension_dialog_title"
+        android:textAppearance="@style/SortTitle"/>
+
+    <ListView
+        android:id="@+id/sorting_dialog_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/res/layout/directory_app_bar.xml b/res/layout/directory_app_bar.xml
new file mode 100644
index 0000000..45864e9
--- /dev/null
+++ b/res/layout/directory_app_bar.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<com.google.android.material.appbar.AppBarLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/app_bar"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/colorBackground">
+
+    <com.google.android.material.appbar.CollapsingToolbarLayout
+        android:id="@+id/collapsing_toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:elevation="3dp"
+        app:titleEnabled="false"
+        app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
+
+        <include layout="@layout/directory_header"/>
+
+        <View
+            android:id="@+id/toolbar_background_layout"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/action_bar_space_height"
+            android:background="?android:attr/colorBackground"
+            app:layout_collapseMode="pin"/>
+
+        <androidx.appcompat.widget.Toolbar
+            android:id="@+id/toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="?android:attr/actionBarSize"
+            android:layout_margin="@dimen/search_bar_margin"
+            android:background="?android:attr/colorBackground"
+            android:theme="?actionBarTheme"
+            android:popupTheme="?actionBarPopupTheme"
+            android:elevation="3dp"
+            app:titleTextAppearance="@style/ToolbarTitle"
+            app:layout_collapseMode="pin">
+
+            <TextView
+                android:id="@+id/searchbar_title"
+                android:layout_width="match_parent"
+                android:layout_height="?android:attr/actionBarSize"
+                android:gravity="center_vertical"
+                android:text="@string/search_bar_hint"
+                android:textAppearance="@style/SearchBarTitle"/>
+
+            <com.android.documentsui.DropdownBreadcrumb
+                android:id="@+id/dropdown_breadcrumb"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginStart="4dp"
+                android:popupTheme="?actionBarPopupTheme"
+                android:background="@android:color/transparent"
+                android:overlapAnchor="true"/>
+
+        </androidx.appcompat.widget.Toolbar>
+
+    </com.google.android.material.appbar.CollapsingToolbarLayout>
+
+</com.google.android.material.appbar.AppBarLayout>
\ No newline at end of file
diff --git a/res/layout/directory_cluster.xml b/res/layout/directory_cluster.xml
deleted file mode 100644
index f4a243d..0000000
--- a/res/layout/directory_cluster.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <!-- dropdown sort widget shows when column headers doesn't. -->
-    <include layout="@layout/dropdown_sort_widget" />
-
-    <!-- column headers are empty on small screens, in portrait or in grid mode. -->
-    <include layout="@layout/column_headers"/>
-
-    <FrameLayout
-        android:id="@+id/container_directory"
-        android:clipToPadding="false"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1" />
-
-    <FrameLayout
-        android:id="@+id/container_save"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="@color/material_grey_50"
-        android:elevation="8dp" />
-
-</LinearLayout>
diff --git a/res/layout/directory_header.xml b/res/layout/directory_header.xml
new file mode 100644
index 0000000..c13e887
--- /dev/null
+++ b/res/layout/directory_header.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="@dimen/action_bar_space_margin"
+    android:orientation="vertical">
+
+    <!-- used for search chip. -->
+    <include layout="@layout/search_chip_row"/>
+
+    <!-- used for apps row. -->
+    <include layout="@layout/apps_row"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/root_info_header_horizontal_padding"
+        android:layout_marginEnd="@dimen/root_info_header_horizontal_padding"
+        android:minHeight="@dimen/root_info_header_height">
+
+        <TextView
+            android:id="@+id/header_title"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:textAppearance="@style/SortTitle"
+            android:textAllCaps="true"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:gravity="start|center_vertical"/>
+
+        <androidx.appcompat.widget.ActionMenuView
+            android:id="@+id/sub_menu"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end|center_vertical"/>
+
+    </LinearLayout>
+
+    <!-- column headers are empty on small screens, in portrait or in grid mode. -->
+    <include layout="@layout/column_headers"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/drag_shadow_layout.xml b/res/layout/drag_shadow_layout.xml
index 1917e25..f424742 100644
--- a/res/layout/drag_shadow_layout.xml
+++ b/res/layout/drag_shadow_layout.xml
@@ -40,7 +40,7 @@
             android:maxLines="1"
             android:ellipsize="end"
             android:textAlignment="viewStart"
-            android:textColor="@color/item_title"
+            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
             android:paddingStart="6dp"
             android:paddingBottom="1dp"/>
 
diff --git a/res/layout/drawer_layout.xml b/res/layout/drawer_layout.xml
index 8eefa3e..a5331d5 100644
--- a/res/layout/drawer_layout.xml
+++ b/res/layout/drawer_layout.xml
@@ -16,47 +16,41 @@
 
 <!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
      floating action buttons) to operate correctly. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:id="@+id/coordinator_layout">
 
-    <android.support.v4.widget.DrawerLayout
+    <androidx.drawerlayout.widget.DrawerLayout
         android:id="@+id/drawer_layout"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
-        <LinearLayout
+        <androidx.coordinatorlayout.widget.CoordinatorLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:orientation="vertical">
 
-            <Toolbar
-                android:id="@+id/toolbar"
-                android:layout_width="match_parent"
-                android:layout_height="?android:attr/actionBarSize"
-                android:background="?android:attr/colorPrimary"
-                android:elevation="8dp"
-                android:theme="?actionBarTheme"
-                android:popupTheme="?actionBarPopupTheme">
-
-                <com.android.documentsui.DropdownBreadcrumb
-                    android:id="@+id/dropdown_breadcrumb"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="4dp"
-                    android:popupTheme="?actionBarPopupTheme"
-                    android:background="@android:color/transparent"
-                    android:overlapAnchor="true" />
-
-            </Toolbar>
-
             <FrameLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent">
+                android:layout_height="match_parent"
+                app:layout_behavior="@string/scrolling_behavior">
 
-                <include layout="@layout/directory_cluster"/>
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:orientation="vertical">
+
+                    <FrameLayout
+                        android:id="@+id/container_directory"
+                        android:clipToPadding="false"
+                        android:layout_width="match_parent"
+                        android:layout_height="0dp"
+                        android:layout_weight="1" />
+
+                </LinearLayout>
 
                 <!-- Drawer edge is a dummy view used to capture hovering event
                      on view edge to open the drawer. (b/28345294) -->
@@ -67,7 +61,17 @@
                     android:layout_height="match_parent"/>
             </FrameLayout>
 
-        </LinearLayout>
+            <androidx.coordinatorlayout.widget.CoordinatorLayout
+                android:id="@+id/container_save"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="bottom|center_horizontal"
+                android:background="?android:attr/colorBackgroundFloating"
+                android:elevation="8dp" />
+
+            <include layout="@layout/directory_app_bar"/>
+
+        </androidx.coordinatorlayout.widget.CoordinatorLayout>
 
         <LinearLayout
             android:id="@+id/drawer_roots"
@@ -75,17 +79,17 @@
             android:layout_height="match_parent"
             android:layout_gravity="start"
             android:orientation="vertical"
-            android:elevation="16dp"
-            android:background="@color/drawer_background">
+            android:elevation="0dp"
+            android:background="?android:attr/colorBackground">
 
-            <Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/roots_toolbar"
                 android:layout_width="match_parent"
                 android:layout_height="?android:attr/actionBarSize"
-                android:background="?android:attr/colorPrimary"
-                android:elevation="8dp"
-                android:theme="?actionBarTheme"
-                android:popupTheme="?actionBarPopupTheme" />
+                android:background="?android:attr/colorBackground"
+                android:elevation="0dp"
+                app:titleTextAppearance="@style/DrawerMenuTitle"
+                app:titleTextColor="?android:colorPrimary"/>
 
             <FrameLayout
                 android:id="@+id/container_roots"
@@ -95,5 +99,5 @@
 
         </LinearLayout>
 
-    </android.support.v4.widget.DrawerLayout>
-</android.support.design.widget.CoordinatorLayout>
+    </androidx.drawerlayout.widget.DrawerLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/layout/dropdown_sort_widget.xml b/res/layout/dropdown_sort_widget.xml
deleted file mode 100644
index 395f52b..0000000
--- a/res/layout/dropdown_sort_widget.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2016 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.
-  -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/dropdown_sort_widget"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/doc_header_height"
-    android:paddingEnd="@dimen/dropdown_sort_widget_margin"
-    android:paddingTop="@dimen/dropdown_sort_widget_margin"
-    android:paddingBottom="@dimen/dropdown_sort_widget_margin"
-    android:background="@drawable/sort_widget_background"
-    android:gravity="center_vertical|end"
-    android:orientation="horizontal">
-
-    <TextView
-        android:id="@+id/sort_dimen_dropdown"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/dropdown_sort_widget_size"
-        android:background="@drawable/dropdown_sort_widget_background"
-        android:paddingStart="12dp"
-        android:paddingEnd="12dp"
-        android:gravity="center"
-        android:fontFamily="sans-serif-medium"
-        android:textSize="@dimen/dropdown_sort_text_size"
-        android:textColor="@color/sort_widget_text_color"/>
-
-    <ImageView
-        android:id="@+id/sort_arrow"
-        android:layout_width="@dimen/dropdown_sort_widget_size"
-        android:layout_height="@dimen/dropdown_sort_widget_size"
-        android:layout_marginStart="4dp"
-        android:background="@drawable/dropdown_sort_widget_background"
-        android:padding="5dp"
-        android:src="@drawable/ic_sort_arrow"
-        android:accessibilityTraversalAfter="@id/sort_dimen_dropdown"/>
-
-</LinearLayout>
diff --git a/res/layout/fixed_layout.xml b/res/layout/fixed_layout.xml
index 4d7f2ea..7f7547f 100644
--- a/res/layout/fixed_layout.xml
+++ b/res/layout/fixed_layout.xml
@@ -16,8 +16,9 @@
 
 <!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
      floating action buttons) to operate correctly. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:id="@+id/coordinator_layout"
@@ -28,22 +29,37 @@
         android:layout_height="match_parent"
         android:orientation="vertical">
 
-        <Toolbar
+        <androidx.appcompat.widget.Toolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="?android:attr/actionBarSize"
-            android:background="?android:attr/colorPrimary"
-            android:elevation="8dp"
+            android:layout_margin="@dimen/search_bar_margin"
+            android:background="?android:attr/colorBackground"
+            android:elevation="3dp"
             android:theme="?actionBarTheme"
-            android:popupTheme="?actionBarPopupTheme">
+            android:popupTheme="?actionBarPopupTheme"
+            app:titleTextAppearance="@style/ToolbarTitle">
+
+            <TextView
+                android:id="@+id/searchbar_title"
+                android:layout_width="match_parent"
+                android:layout_height="?android:attr/actionBarSize"
+                android:layout_marginStart="@dimen/search_bar_text_margin_start"
+                android:layout_marginEnd="@dimen/search_bar_text_margin_end"
+                android:paddingStart="@dimen/search_bar_icon_padding"
+                android:gravity="center_vertical"
+                android:text="@string/search_bar_hint"
+                android:textAppearance="@style/SearchBarTitle"
+                android:drawableStart="@drawable/ic_menu_search"
+                android:drawablePadding="@dimen/search_bar_icon_padding"/>
 
             <com.android.documentsui.HorizontalBreadcrumb
                 android:id="@+id/horizontal_breadcrumb"
                 android:layout_marginRight="20dp"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
+                android:layout_height="match_parent" />
 
-        </Toolbar>
+        </androidx.appcompat.widget.Toolbar>
 
         <LinearLayout
             android:layout_width="match_parent"
@@ -57,12 +73,32 @@
                 android:layout_width="256dp"
                 android:layout_height="match_parent" />
 
-            <include layout="@layout/directory_cluster"
-                android:layout_width="0dp"
-                android:elevation="8dp" />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:orientation="vertical"
+                android:elevation="8dp">
+
+                <include layout="@layout/directory_header" />
+
+                <FrameLayout
+                    android:id="@+id/container_directory"
+                    android:clipToPadding="false"
+                    android:layout_width="match_parent"
+                    android:layout_height="0dp"
+                    android:layout_weight="1" />
+
+                <androidx.coordinatorlayout.widget.CoordinatorLayout
+                    android:id="@+id/container_save"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:background="?android:attr/colorBackgroundFloating"
+                    android:elevation="8dp" />
+
+            </LinearLayout>
 
         </LinearLayout>
 
     </LinearLayout>
 
-</android.support.design.widget.CoordinatorLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/layout/fragment_directory.xml b/res/layout/fragment_directory.xml
index e9db1dc..dda8412 100644
--- a/res/layout/fragment_directory.xml
+++ b/res/layout/fragment_directory.xml
@@ -19,7 +19,7 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/directory_background"
+    android:background="?android:attr/colorBackground"
     android:outlineProvider="bounds"
     android:elevation="4dp"
     android:orientation="vertical">
@@ -34,10 +34,11 @@
 
     <com.android.documentsui.dirlist.DocumentsSwipeRefreshLayout
         android:id="@+id/refresh_layout"
+        android:background="@android:color/transparent"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
-        <android.support.v7.widget.RecyclerView
+        <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/dir_list"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
@@ -48,11 +49,8 @@
             android:clipToPadding="false"
             android:scrollbars="none"
             android:drawSelectorOnTop="true"
-            app:fastScrollEnabled="true"
-            app:fastScrollVerticalThumbDrawable="@drawable/fast_scroll_thumb_drawable"
-            app:fastScrollVerticalTrackDrawable="@drawable/fast_scroll_track_drawable"
-            app:fastScrollHorizontalThumbDrawable="@drawable/fast_scroll_thumb_drawable"
-            app:fastScrollHorizontalTrackDrawable="@drawable/fast_scroll_track_drawable"/>
+            android:overScrollMode="never"
+            app:fastScrollEnabled="false"/>
 
     </com.android.documentsui.dirlist.DocumentsSwipeRefreshLayout>
 
diff --git a/res/layout/fragment_pick.xml b/res/layout/fragment_pick.xml
index dab5a9e..c18afa0 100644
--- a/res/layout/fragment_pick.xml
+++ b/res/layout/fragment_pick.xml
@@ -16,24 +16,27 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/bottom_bar_height"
+    android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:baselineAligned="false"
-    android:gravity="end"
-    android:paddingEnd="@dimen/bottom_bar_padding_end">
-    <TextView
-        style="@style/BottomBarButton"
+    android:gravity="center_vertical|end"
+    android:paddingStart="@dimen/bottom_bar_padding"
+    android:paddingEnd="@dimen/bottom_bar_padding">
+
+    <com.google.android.material.button.MaterialButton
         android:id="@android:id/button2"
-        android:layout_width="@dimen/bottom_bar_negative_button_width"
-        android:background="@android:color/transparent"
-        android:text="@android:string/cancel"
-        android:textColor="@color/primary"/>
-    <TextView
-        style="@style/BottomBarButton"
+        style="?attr/materialButtonOutlinedStyle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="4dp"
+        android:layout_marginEnd="4dp"
+        android:text="@android:string/cancel"/>
+
+    <com.google.android.material.button.MaterialButton
         android:id="@android:id/button1"
-        android:layout_width="@dimen/bottom_bar_positive_button_width"
-        android:layout_marginStart="@dimen/bottom_bar_positive_button_margin_start"
-        android:background="@drawable/bottom_bar_positive_button_background"
-        android:elevation="@dimen/bottom_bar_positive_button_elevation"
-        android:textColor="@android:color/white"/>
+        style="?attr/materialButtonStyle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="4dp"
+        android:layout_marginEnd="4dp"/>
 </LinearLayout>
diff --git a/res/layout/fragment_roots.xml b/res/layout/fragment_roots.xml
index 8314b81..af78619 100644
--- a/res/layout/fragment_roots.xml
+++ b/res/layout/fragment_roots.xml
@@ -19,7 +19,5 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:paddingTop="8dp"
-    android:listSelector="@drawable/root_list_selector"
     android:keyboardNavigationCluster="true"
-    android:divider="@null"
-    android:background="@drawable/roots_list_border" />
+    android:divider="@null"/>
diff --git a/res/layout/fragment_save.xml b/res/layout/fragment_save.xml
index df6b8c5..b3f3c0b 100644
--- a/res/layout/fragment_save.xml
+++ b/res/layout/fragment_save.xml
@@ -16,13 +16,12 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/bottom_bar_height"
+    android:layout_height="wrap_content"
     android:paddingStart="@dimen/list_item_padding"
-    android:paddingEnd="@dimen/bottom_bar_padding_end"
+    android:paddingEnd="@dimen/bottom_bar_padding"
     android:orientation="horizontal"
     android:baselineAligned="false"
     android:gravity="center_vertical"
-    android:fitsSystemWindows="true"
     android:minHeight="?android:attr/listPreferredItemHeightSmall">
 
     <FrameLayout
@@ -51,15 +50,14 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent">
 
-        <TextView
-            style="@style/BottomBarButton"
+        <com.google.android.material.button.MaterialButton
             android:id="@android:id/button1"
-            android:layout_width="@dimen/bottom_bar_positive_button_width"
-            android:layout_marginStart="@dimen/bottom_bar_positive_button_margin_start"
-            android:background="@drawable/bottom_bar_positive_button_background"
-            android:text="@string/menu_save"
-            android:elevation="@dimen/bottom_bar_positive_button_elevation"
-            android:textColor="@android:color/white"/>
+            style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="4dp"
+            android:layout_marginEnd="4dp"
+            android:text="@string/menu_save"/>
 
         <ProgressBar
             android:id="@android:id/progress"
diff --git a/res/layout/fragment_search.xml b/res/layout/fragment_search.xml
new file mode 100644
index 0000000..c6377ae
--- /dev/null
+++ b/res/layout/fragment_search.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="?android:attr/colorBackground">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        android:layout_margin="@dimen/search_bar_margin"
+        android:theme="?actionBarTheme"
+        app:navigationIcon="@drawable/ic_arrow_back"
+        app:navigationContentDescription="@string/abc_toolbar_collapse_description">
+
+        <androidx.appcompat.widget.SearchView
+            android:id="@+id/search_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+    </androidx.appcompat.widget.Toolbar>
+
+    <!-- used for search chip. -->
+    <include layout="@layout/search_chip_row"/>
+
+    <ListView
+        android:id="@+id/history_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:divider="@null"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/inspector_activity.xml b/res/layout/inspector_activity.xml
index f48bc92..df28d49 100644
--- a/res/layout/inspector_activity.xml
+++ b/res/layout/inspector_activity.xml
@@ -14,26 +14,107 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/inspector_root"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <Toolbar
-        android:id="@+id/toolbar"
-        android:title="@string/inspector_title"
+    <com.google.android.material.appbar.AppBarLayout
+        android:id="@+id/app_bar"
         android:layout_width="match_parent"
-        android:layout_height="?android:attr/actionBarSize"
-        android:background="?android:attr/colorPrimary"
-        android:elevation="8dp"
-        android:theme="?actionBarTheme"
-        android:popupTheme="?actionBarPopupTheme">
-    </Toolbar>
+        android:layout_height="wrap_content"
+        android:background="?android:colorBackground">
 
-    <FrameLayout
-        android:id="@+id/fragment_container"
+        <com.google.android.material.appbar.CollapsingToolbarLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="?android:attr/actionBarSize"
+            app:titleEnabled="false"
+            app:statusBarScrim="@android:color/transparent"
+            app:layout_scrollFlags="scroll|exitUntilCollapsed">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+
+                <android.widget.Space
+                    android:layout_width="match_parent"
+                    android:layout_height="?android:attr/actionBarSize"/>
+
+                <com.android.documentsui.inspector.HeaderView
+                    android:id="@+id/inspector_header_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/inspector_header_height"
+                    app:layout_collapseMode="parallax"/>
+            </LinearLayout>
+
+            <androidx.appcompat.widget.Toolbar
+                android:id="@+id/toolbar"
+                android:layout_width="match_parent"
+                android:layout_height="?android:attr/actionBarSize"
+                android:background="?android:attr/colorBackground"
+                android:theme="?actionBarTheme"
+                app:title="@string/inspector_title"
+                app:titleTextAppearance="@style/ToolbarTitle"
+                app:layout_collapseMode="pin">
+            </androidx.appcompat.widget.Toolbar>
+        </com.google.android.material.appbar.CollapsingToolbarLayout>
+    </com.google.android.material.appbar.AppBarLayout>
+
+    <androidx.core.widget.NestedScrollView
+        android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
-    </FrameLayout>
+        android:layout_height="match_parent"
+        android:overScrollMode="never"
+        app:behavior_overlapTop="10dp"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
 
-</LinearLayout>
+        <LinearLayout
+            android:id="@+id/inspector_container"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@drawable/bottom_sheet_dialog_background"
+            android:paddingBottom="5dp">
+
+            <com.android.documentsui.inspector.DetailsView
+                android:id="@+id/inspector_details_view"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <com.android.documentsui.inspector.MediaView
+                android:id="@+id/inspector_media_view"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <com.android.documentsui.inspector.actions.ActionView
+                android:id="@+id/inspector_show_in_provider_view"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:visibility="gone"/>
+
+            <com.android.documentsui.inspector.actions.ActionView
+                android:id="@+id/inspector_app_defaults_view"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:visibility="gone"/>
+
+            <com.android.documentsui.inspector.DebugView
+                android:id="@+id/inspector_debug_view"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="20dp"
+                android:visibility="gone" />
+
+        </LinearLayout>
+    </androidx.core.widget.NestedScrollView>
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/layout/inspector_fragment.xml b/res/layout/inspector_fragment.xml
deleted file mode 100644
index 24f0fdb..0000000
--- a/res/layout/inspector_fragment.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2017 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.
--->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <LinearLayout
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingBottom="5dp">
-
-        <com.android.documentsui.inspector.HeaderView
-            android:id="@+id/inspector_header_view"
-            android:layout_width="match_parent"
-            android:paddingBottom="5dp"
-            android:layout_height="@dimen/inspector_header_height" />
-
-        <com.android.documentsui.inspector.DetailsView
-            android:id="@+id/inspector_details_view"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
-
-        <com.android.documentsui.inspector.MediaView
-            android:id="@+id/inspector_media_view"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
-
-        <com.android.documentsui.inspector.actions.ActionView
-            android:id="@+id/inspector_show_in_provider_view"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"/>
-
-        <com.android.documentsui.inspector.actions.ActionView
-            android:id="@+id/inspector_app_defaults_view"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"/>
-
-        <com.android.documentsui.inspector.DebugView
-            android:id="@+id/inspector_debug_view"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingTop="20dp"
-            android:visibility="gone" />
-
-    </LinearLayout>
-</ScrollView>
diff --git a/res/layout/inspector_header.xml b/res/layout/inspector_header.xml
index d621801..94a0927 100644
--- a/res/layout/inspector_header.xml
+++ b/res/layout/inspector_header.xml
@@ -22,23 +22,8 @@
         android:id="@+id/inspector_thumbnail"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:scaleType="fitCenter"
         android:alpha="0.0"
-        android:background="@android:color/white" />
-
-    <TextView
-        android:id="@+id/inspector_file_title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="20sp"
-        android:paddingTop="5dp"
-        android:paddingBottom="5dp"
-        android:paddingStart="16dp"
-        android:paddingEnd="16dp"
-        android:textColor="@android:color/white"
-        android:layout_gravity="center_vertical"
-        android:background="@color/inspector_title_background"
-        android:textIsSelectable="true"
-        android:textAlignment="viewStart"
-        android:layout_alignBottom="@+id/inspector_thumbnail" />
+        android:background="?android:colorBackgroundFloating" />
 
 </RelativeLayout>
diff --git a/res/layout/inspector_section_title.xml b/res/layout/inspector_section_title.xml
index 33889a8..358b961 100644
--- a/res/layout/inspector_section_title.xml
+++ b/res/layout/inspector_section_title.xml
@@ -23,17 +23,23 @@
     android:paddingStart="10dp"
     android:paddingEnd="10dp">
 
+    <!--Empty view for keeping divider when title is gone-->
+    <android.widget.Space
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content">
+    </android.widget.Space >
+
     <TextView
         android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:id="@+id/inspector_header_title"
-        android:paddingStart="6dp"
-        android:paddingEnd="6dp"
-        android:paddingTop="5dp"
-        android:paddingBottom="5dp"
+        android:paddingStart="16dp"
+        android:paddingEnd="16dp"
+        android:paddingTop="25dp"
+        android:paddingBottom="25dp"
         android:layout_gravity="center_vertical"
-        android:fontFamily="sans-serif-medium"
-        android:textSize="15sp"
+        android:clickable="false"
+        android:textAppearance="@style/ToolbarTitle"
         android:textAlignment="viewStart"
-        android:textColor="@color/inspector_section_title"/>
+        android:textIsSelectable="true"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/item_dir_grid.xml b/res/layout/item_dir_grid.xml
index da923e9..06948f6 100644
--- a/res/layout/item_dir_grid.xml
+++ b/res/layout/item_dir_grid.xml
@@ -21,19 +21,24 @@
      to focus and selection states, some of which are specific to keyboard
      when touch mode is not enable. So, if you, heroic engineer of the future,
      decide to rip these out, please be sure to check out focus and keyboards. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/item_root"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_margin="@dimen/grid_item_margin"
-    android:orientation="vertical"
-    android:background="@drawable/grid_item_background"
-    android:elevation="@dimen/grid_item_elevation"
+    android:layout_margin="2dp"
     android:focusable="true">
 
-    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    <com.google.android.material.card.MaterialCardView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:duplicateParentState="true">
+        android:layout_margin="2dp"
+        android:elevation="0dp"
+        android:duplicateParentState="true"
+        app:cardElevation="0dp"
+        app:strokeWidth="1dp"
+        app:strokeColor="?android:strokeColor">
 
         <!-- The height is 48px.
              paddingTop (9dp) + @dimen/check_icon_size (30dp) + paddingBottom (9dp) -->
@@ -41,26 +46,26 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:orientation="horizontal"
-            android:paddingBottom="9dp"
-            android:paddingLeft="9dp"
-            android:paddingRight="12dp"
-            android:paddingTop="9dp"
+            android:background="?android:attr/colorBackground"
             android:gravity="center_vertical">
 
             <FrameLayout
+                android:id="@+id/icon"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:pointerIcon="hand"
-                android:layout_marginEnd="8dp" >
+                android:paddingBottom="9dp"
+                android:paddingStart="9dp"
+                android:paddingEnd="8dp"
+                android:paddingTop="9dp">
 
                 <ImageView
                     android:id="@+id/icon_mime_sm"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
+                    android:layout_width="@dimen/grid_item_icon_size"
+                    android:layout_height="@dimen/grid_item_icon_size"
                     android:layout_gravity="center"
                     android:contentDescription="@null"
-                    android:scaleType="centerInside"
-                    android:src="@drawable/ic_doc_folder" />
+                    android:scaleType="centerInside"/>
 
                 <ImageView
                     android:id="@+id/icon_check"
@@ -69,7 +74,7 @@
                     android:alpha="0"
                     android:contentDescription="@null"
                     android:scaleType="fitCenter"
-                    android:src="@drawable/ic_check_circle" />
+                    android:src="@drawable/ic_check_circle"/>
 
             </FrameLayout>
 
@@ -80,20 +85,22 @@
                 android:ellipsize="end"
                 android:singleLine="true"
                 android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-                android:textColor="@color/item_title" />
+                android:textAppearance="@style/CardPrimaryText"
+                android:layout_marginBottom="9dp"
+                android:layout_marginEnd="12dp"
+                android:layout_marginTop="9dp"/>
 
         </LinearLayout>
 
-        <!-- An overlay that draws the item border when it is focused. -->
+    </com.google.android.material.card.MaterialCardView>
 
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:background="@drawable/item_doc_grid_border"
-            android:contentDescription="@null"
-            android:duplicateParentState="true" />
+    <!-- An overlay that draws the item border when it is focused. -->
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="1dp"
+        android:background="@drawable/item_doc_grid_border_rounded"
+        android:contentDescription="@null"
+        android:duplicateParentState="true"/>
 
-    </FrameLayout>
-
-</LinearLayout>
\ No newline at end of file
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/item_doc_grid.xml b/res/layout/item_doc_grid.xml
index e86d140..d8f6eaf 100644
--- a/res/layout/item_doc_grid.xml
+++ b/res/layout/item_doc_grid.xml
@@ -20,138 +20,176 @@
      to focus and selection states, some of which are specific to keyboard
      when touch mode is not enable. So, if you, heroic engineer of the future,
      decide to rip these out, please be sure to check out focus and keyboards. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/item_root"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_margin="@dimen/grid_item_margin"
-    android:orientation="vertical"
-    android:background="@drawable/grid_item_background"
-    android:elevation="@dimen/grid_item_elevation"
+    android:layout_margin="2dp"
     android:focusable="true">
 
-    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    <com.google.android.material.card.MaterialCardView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:duplicateParentState="true">
-
-        <!-- Main item thumbnail.  Comprised of two overlapping images, the
-             visibility of which is controlled by code in
-             DirectoryFragment.java. -->
-
-        <FrameLayout
-            android:id="@+id/thumbnail"
-            android:background="@drawable/grid_item_background"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-
-            <com.android.documentsui.GridItemThumbnail
-                android:id="@+id/icon_thumb"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:scaleType="centerCrop"
-                android:contentDescription="@null"
-                android:tint="@color/item_doc_grid_tint"
-                android:tintMode="src_over" />
-
-            <com.android.documentsui.GridItemThumbnail
-                android:id="@+id/icon_mime_lg"
-                android:layout_width="@dimen/icon_size"
-                android:layout_height="@dimen/icon_size"
-                android:layout_gravity="center"
-                android:scaleType="fitCenter"
-                android:contentDescription="@null" />
-
-        </FrameLayout>
-
-        <!-- Item nameplate.  Has a mime-type icon and some text fields (title,
-             size, mod-time, etc). -->
+        android:layout_margin="2dp"
+        android:elevation="0dp"
+        android:duplicateParentState="true"
+        app:cardElevation="0dp"
+        app:strokeWidth="1dp"
+        app:strokeColor="?android:strokeColor">
 
         <RelativeLayout
-            android:id="@+id/nameplate"
-            android:background="@drawable/grid_item_background"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/thumbnail"
-            android:paddingTop="8dp"
-            android:paddingBottom="8dp"
-            android:paddingLeft="12dp"
-            android:paddingRight="12dp">
+            android:duplicateParentState="true">
 
-            <ImageView
-                android:id="@+id/icon_mime_sm"
-                android:layout_width="@dimen/grid_item_icon_size"
-                android:layout_height="@dimen/grid_item_icon_size"
-                android:layout_marginEnd="8dp"
-                android:layout_alignParentStart="true"
-                android:layout_centerVertical="true"
-                android:scaleType="center"
-                android:pointerIcon="hand"
-                android:contentDescription="@null"/>
+            <!-- Main item thumbnail.  Comprised of two overlapping images, the
+                 visibility of which is controlled by code in
+                 DirectoryFragment.java. -->
 
-            <ImageView
-                android:id="@+id/icon_check"
-                android:src="@drawable/ic_check_circle"
-                android:alpha="0"
-                android:layout_width="@dimen/check_icon_size"
-                android:layout_height="@dimen/check_icon_size"
-                android:layout_marginEnd="8dp"
-                android:layout_alignParentStart="true"
-                android:layout_centerVertical="true"
-                android:scaleType="fitCenter"
-                android:pointerIcon="hand"
-                android:contentDescription="@null"/>
+            <FrameLayout
+                android:id="@+id/thumbnail"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
 
-            <TextView
-                android:id="@android:id/title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                <com.android.documentsui.GridItemThumbnail
+                    android:id="@+id/icon_thumb"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:scaleType="centerCrop"
+                    android:contentDescription="@null"
+                    android:tint="?attr/gridItemTint"
+                    android:tintMode="src_over"/>
+
+                <com.android.documentsui.GridItemThumbnail
+                    android:id="@+id/icon_mime_lg"
+                    android:layout_width="@dimen/icon_size"
+                    android:layout_height="@dimen/icon_size"
+                    android:layout_gravity="center"
+                    android:scaleType="fitCenter"
+                    android:contentDescription="@null"/>
+
+            </FrameLayout>
+
+            <FrameLayout
+                android:id="@+id/preview_icon"
+                android:layout_width="@dimen/button_touch_size"
+                android:layout_height="@dimen/button_touch_size"
                 android:layout_alignParentTop="true"
-                android:layout_toEndOf="@id/icon_mime_sm"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-                android:textColor="@color/item_title" />
+                android:layout_alignParentEnd="true"
+                android:pointerIcon="hand"
+                android:focusable="true"
+                android:clickable="true">
 
-            <TextView
-                android:id="@+id/details"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_toEndOf="@id/icon_mime_sm"
-                android:layout_below="@android:id/title"
-                android:layout_marginEnd="4dp"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                android:textColor="@color/item_details" />
+                <ImageView
+                    android:layout_width="@dimen/zoom_icon_size"
+                    android:layout_height="@dimen/zoom_icon_size"
+                    android:padding="2dp"
+                    android:layout_gravity="center"
+                    android:background="@drawable/circle_button_background"
+                    android:scaleType="fitCenter"
+                    android:src="@drawable/ic_zoom_out"/>
 
-            <TextView
-                android:id="@+id/date"
-                android:layout_width="wrap_content"
+            </FrameLayout>
+
+            <!-- Item nameplate.  Has a mime-type icon and some text fields (title,
+                 size, mod-time, etc). -->
+
+            <LinearLayout
+                android:id="@+id/nameplate"
+                android:background="?android:attr/colorBackground"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_below="@android:id/title"
-                android:layout_toEndOf="@id/details"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                android:textColor="@color/item_details" />
+                android:layout_below="@id/thumbnail">
+
+                <FrameLayout
+                    android:id="@+id/icon"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_centerVertical="true"
+                    android:pointerIcon="hand"
+                    android:paddingTop="8dp"
+                    android:paddingBottom="8dp"
+                    android:paddingStart="12dp"
+                    android:paddingEnd="8dp">
+
+                    <ImageView
+                        android:id="@+id/icon_mime_sm"
+                        android:layout_width="@dimen/grid_item_icon_size"
+                        android:layout_height="@dimen/grid_item_icon_size"
+                        android:layout_gravity="center"
+                        android:scaleType="center"
+                        android:contentDescription="@null"/>
+
+                    <ImageView
+                        android:id="@+id/icon_check"
+                        android:src="@drawable/ic_check_circle"
+                        android:alpha="0"
+                        android:layout_width="@dimen/check_icon_size"
+                        android:layout_height="@dimen/check_icon_size"
+                        android:layout_gravity="center"
+                        android:scaleType="fitCenter"
+                        android:contentDescription="@null"/>
+
+                </FrameLayout>
+
+                <RelativeLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingBottom="8dp"
+                    android:paddingTop="8dp"
+                    android:paddingEnd="12dp">
+
+                    <TextView
+                        android:id="@android:id/title"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_alignParentTop="true"
+                        android:layout_alignParentStart="true"
+                        android:singleLine="true"
+                        android:ellipsize="end"
+                        android:textAlignment="viewStart"
+                        android:textAppearance="@style/CardPrimaryText"/>
+
+                    <TextView
+                        android:id="@+id/details"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_below="@android:id/title"
+                        android:layout_marginEnd="4dp"
+                        android:singleLine="true"
+                        android:ellipsize="end"
+                        android:textAlignment="viewStart"
+                        android:textAppearance="@android:style/TextAppearance.Material.Caption"/>
+
+                    <TextView
+                        android:id="@+id/date"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_below="@android:id/title"
+                        android:layout_toEndOf="@id/details"
+                        android:singleLine="true"
+                        android:ellipsize="end"
+                        android:textAlignment="viewStart"
+                        android:textAppearance="@android:style/TextAppearance.Material.Caption"/>
+
+                </RelativeLayout>
+
+            </LinearLayout>
 
         </RelativeLayout>
 
-        <!-- An overlay that draws the item border when it is focused. -->
-        <View
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignBottom="@id/nameplate"
-            android:layout_alignTop="@id/thumbnail"
-            android:layout_alignLeft="@id/thumbnail"
-            android:layout_alignRight="@id/thumbnail"
-            android:contentDescription="@null"
-            android:background="@drawable/item_doc_grid_border"
-            android:duplicateParentState="true" />
+    </com.google.android.material.card.MaterialCardView>
 
-    </RelativeLayout>
+    <!-- An overlay that draws the item border when it is focused. -->
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="1dp"
+        android:background="@drawable/item_doc_grid_border_rounded"
+        android:contentDescription="@null"
+        android:duplicateParentState="true"/>
 
-</LinearLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/res/layout/item_doc_header_message.xml b/res/layout/item_doc_header_message.xml
index 3c48950..352d50c 100644
--- a/res/layout/item_doc_header_message.xml
+++ b/res/layout/item_doc_header_message.xml
@@ -13,45 +13,37 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:animateLayoutChanges="true"
+    android:id="@+id/message_container"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:orientation="horizontal"
-    android:id="@+id/message_container"
-    android:paddingLeft="@dimen/header_message_horizontal_padding"
-    android:paddingRight="@dimen/header_message_horizontal_padding">
+    android:minHeight="?android:attr/listPreferredItemHeightSmall">
 
-        <FrameLayout
-            android:layout_height="@dimen/icon_size"
-            android:layout_width="@dimen/icon_size"
-            android:layout_gravity="center_vertical"
-            >
+    <ImageView
+        android:contentDescription="@null"
+        android:id="@+id/message_icon"
+        android:layout_height="@dimen/icon_size"
+        android:layout_width="@dimen/icon_size"
+        android:layout_marginStart="@dimen/list_item_padding"
+        android:layout_marginEnd="@dimen/list_item_padding"
+        android:scaleType="centerInside"/>
 
-            <ImageView
-                android:contentDescription="@null"
-                android:id="@+id/message_icon"
-                android:layout_height="match_parent"
-                android:layout_width="wrap_content"
-                android:scaleType="centerInside"/>
+    <TextView
+        android:id="@+id/message_textview"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_marginStart="0dp"
+        android:layout_marginEnd="@dimen/list_item_padding"
+        android:layout_toEndOf="@+id/message_icon"
+        android:selectAllOnFocus="true"/>
 
-        </FrameLayout>
-
-        <TextView
-            android:id="@+id/message_textview"
-            android:layout_gravity="center_vertical"
-            android:layout_height="wrap_content"
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            android:selectAllOnFocus="true"/>
-
-        <Button
-            android:id="@+id/button_dismiss"
-            android:layout_gravity="end"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:text="@string/button_dismiss"
-            style="?android:attr/buttonBarPositiveButtonStyle"/>
-
-</LinearLayout>
+    <Button
+        android:id="@+id/button_dismiss"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_alignEnd="@+id/message_textview"
+        android:layout_below="@+id/message_textview"
+        android:text="@android:string/ok"
+        style="?attr/materialButtonStyle"/>
+</RelativeLayout>
diff --git a/res/layout/item_doc_inflated_message.xml b/res/layout/item_doc_inflated_message.xml
index caa5145..07a95d8 100644
--- a/res/layout/item_doc_inflated_message.xml
+++ b/res/layout/item_doc_inflated_message.xml
@@ -19,21 +19,19 @@
     android:id="@android:id/empty"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/directory_background"
-    android:focusable="true"
-    android:clickable="true">
+    android:background="?android:attr/colorBackground"
+    android:focusable="true">
 
     <RelativeLayout
         android:id="@+id/content"
-        android:gravity="center"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
         <ImageView
             android:id="@+id/artwork"
-            android:layout_above="@+id/message"
             android:layout_height="wrap_content"
             android:layout_width="fill_parent"
+            android:layout_alignParentTop="true"
             android:layout_marginBottom="25dp"
             android:scaleType="fitCenter"
             android:maxHeight="250dp"
@@ -41,12 +39,12 @@
             android:contentDescription="@null"/>
 
         <TextView
-            android:id="@id/message"
+            android:id="@+id/message"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
+            android:layout_below="@+id/artwork"
             android:layout_centerHorizontal="true"
-            style="@android:style/TextAppearance.Material.Subhead"/>
+            style="?android:attr/textAppearanceListItem"/>
 
     </RelativeLayout>
 
diff --git a/res/layout/item_doc_list.xml b/res/layout/item_doc_list.xml
index 00b9aa2..c485edb 100644
--- a/res/layout/item_doc_list.xml
+++ b/res/layout/item_doc_list.xml
@@ -15,7 +15,9 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/item_root"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/list_item_background"
@@ -29,16 +31,17 @@
         android:baselineAligned="false"
         android:gravity="center_vertical"
         android:minHeight="@dimen/list_item_height"
-        android:orientation="horizontal"
-        android:paddingEnd="@dimen/list_item_padding"
-        android:paddingStart="@dimen/list_item_padding" >
+        android:orientation="horizontal" >
 
         <FrameLayout
             android:id="@android:id/icon"
             android:pointerIcon="hand"
-            android:layout_width="@dimen/list_item_thumbnail_size"
-            android:layout_height="@dimen/list_item_thumbnail_size"
-            android:layout_marginEnd="16dp" >
+            android:layout_width="@dimen/list_item_width"
+            android:layout_height="@dimen/list_item_height"
+            android:paddingBottom="@dimen/list_item_icon_padding"
+            android:paddingTop="@dimen/list_item_icon_padding"
+            android:paddingEnd="16dp"
+            android:paddingStart="@dimen/list_item_padding" >
 
             <ImageView
                 android:id="@+id/icon_mime"
@@ -71,7 +74,8 @@
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:orientation="vertical"
-            android:layout_gravity="center_vertical" >
+            android:layout_gravity="center_vertical"
+            android:layout_marginEnd="@dimen/list_item_padding" >
 
             <TextView
                 android:id="@android:id/title"
@@ -81,8 +85,7 @@
                 android:ellipsize="end"
                 android:singleLine="true"
                 android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-                android:textColor="@color/item_title" />
+                android:textAppearance="?android:attr/textAppearanceListItem" />
 
             <LinearLayout
                 android:id="@+id/line2"
@@ -94,49 +97,56 @@
 
                 <TextView
                     android:id="@+id/date"
-                    android:layout_width="90dp"
+                    android:layout_width="0dp"
                     android:layout_height="wrap_content"
+                    android:layout_weight="0.4"
                     android:ellipsize="end"
                     android:singleLine="true"
                     android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                    android:textColor="@color/item_details" />
+                    android:textAppearance="@android:style/TextAppearance.Material.Caption"/>
 
                 <TextView
                     android:id="@+id/size"
-                    android:layout_width="90dp"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="8dp"
-                    android:ellipsize="end"
-                    android:singleLine="true"
-                    android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                    android:textColor="@color/item_details" />
-
-                <TextView
-                    android:id="@+id/file_type"
-                    android:layout_width="90dp"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="8dp"
-                    android:ellipsize="end"
-                    android:singleLine="true"
-                    android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                    android:textColor="@color/item_details" />
-
-                <TextView
-                    android:id="@android:id/summary"
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_marginStart="8dp"
-                    android:layout_weight="1"
+                    android:layout_weight="0.3"
                     android:ellipsize="end"
                     android:singleLine="true"
                     android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                    android:textColor="@color/item_details" />
+                    android:textAppearance="@android:style/TextAppearance.Material.Caption"/>
+
+                <TextView
+                    android:id="@+id/file_type"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="8dp"
+                    android:layout_weight="0.3"
+                    android:ellipsize="end"
+                    android:singleLine="true"
+                    android:textAlignment="viewStart"
+                    android:textAppearance="@android:style/TextAppearance.Material.Caption"/>
             </LinearLayout>
         </LinearLayout>
+
+        <FrameLayout
+            android:id="@+id/preview_icon"
+            android:layout_width="@dimen/list_item_width"
+            android:layout_height="@dimen/list_item_height"
+            android:padding="@dimen/list_item_icon_padding"
+            android:focusable="true"
+            android:clickable="true">
+
+            <ImageView
+                android:layout_width="@dimen/check_icon_size"
+                android:layout_height="@dimen/check_icon_size"
+                android:layout_gravity="center"
+                android:scaleType="fitCenter"
+                android:tint="?android:attr/colorControlNormal"
+                android:src="@drawable/ic_zoom_out"/>
+
+        </FrameLayout>
+
     </LinearLayout>
 
 </LinearLayout>
diff --git a/res/layout/item_history.xml b/res/layout/item_history.xml
new file mode 100644
index 0000000..7bb76b3
--- /dev/null
+++ b/res/layout/item_history.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:gravity="center_vertical">
+
+    <ImageView
+        android:layout_width="@dimen/button_touch_size"
+        android:layout_height="@dimen/button_touch_size"
+        android:src="@drawable/ic_history"
+        android:scaleType="centerInside"/>
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItem"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:gravity="center_vertical"/>
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/button_touch_size"
+        android:layout_height="@dimen/button_touch_size"
+        android:background="@drawable/generic_ripple_background"
+        android:src="@drawable/ic_action_clear"
+        android:scaleType="centerInside"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/item_photo_grid.xml b/res/layout/item_photo_grid.xml
new file mode 100644
index 0000000..a1ceea0
--- /dev/null
+++ b/res/layout/item_photo_grid.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<!-- FYI: This layout has an extra top level container view that was previously used
+     to allow for the insertion of debug info. The debug info is now gone, but the
+     container remains because there is a high likelihood of UI regression relating
+     to focus and selection states, some of which are specific to keyboard
+     when touch mode is not enable. So, if you, heroic engineer of the future,
+     decide to rip these out, please be sure to check out focus and keyboards. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:layout_margin="4dp"
+    android:background="@drawable/grid_item_background"
+    android:elevation="@dimen/grid_item_elevation"
+    android:focusable="true">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:duplicateParentState="true">
+
+        <!-- Main item thumbnail. Comprised of two overlapping images, the
+             visibility of which is controlled by code in
+             DirectoryFragment.java. -->
+
+        <FrameLayout
+            android:id="@+id/thumbnail"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <com.android.documentsui.GridItemThumbnail
+                android:id="@+id/icon_thumb"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scaleType="centerCrop"
+                android:contentDescription="@null"
+                android:tint="?attr/gridItemTint"
+                android:tintMode="src_over"/>
+
+            <com.android.documentsui.GridItemThumbnail
+                android:id="@+id/icon_mime_lg"
+                android:layout_width="@dimen/icon_size"
+                android:layout_height="@dimen/icon_size"
+                android:layout_gravity="center"
+                android:scaleType="fitCenter"
+                android:contentDescription="@null"/>
+
+        </FrameLayout>
+
+        <FrameLayout
+            android:layout_width="@dimen/button_touch_size"
+            android:layout_height="@dimen/button_touch_size"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentStart="true"
+            android:pointerIcon="hand">
+
+            <ImageView
+                android:id="@+id/icon_check"
+                android:src="@drawable/ic_check_circle"
+                android:alpha="0"
+                android:layout_width="@dimen/check_icon_size"
+                android:layout_height="@dimen/check_icon_size"
+                android:layout_gravity="center"
+                android:scaleType="fitCenter"
+                android:contentDescription="@null"/>
+
+        </FrameLayout>
+
+        <FrameLayout
+            android:id="@+id/preview_icon"
+            android:layout_width="@dimen/button_touch_size"
+            android:layout_height="@dimen/button_touch_size"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentEnd="true"
+            android:pointerIcon="hand"
+            android:focusable="true"
+            android:clickable="true">
+
+            <ImageView
+                android:layout_width="@dimen/zoom_icon_size"
+                android:layout_height="@dimen/zoom_icon_size"
+                android:padding="2dp"
+                android:layout_gravity="center"
+                android:background="@drawable/circle_button_background"
+                android:scaleType="fitCenter"
+                android:src="@drawable/ic_zoom_out"/>
+
+        </FrameLayout>
+
+        <!-- An overlay that draws the item border when it is focused. -->
+        <View
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignBottom="@id/thumbnail"
+            android:layout_alignTop="@id/thumbnail"
+            android:layout_alignLeft="@id/thumbnail"
+            android:layout_alignRight="@id/thumbnail"
+            android:contentDescription="@null"
+            android:background="@drawable/item_doc_grid_border"
+            android:duplicateParentState="true"/>
+
+    </RelativeLayout>
+
+</LinearLayout>
diff --git a/res/layout/item_root.xml b/res/layout/item_root.xml
index d47fa4f..8d0f86b 100644
--- a/res/layout/item_root.xml
+++ b/res/layout/item_root.xml
@@ -18,15 +18,15 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="48dp"
-    android:paddingStart="25dp"
+    android:minHeight="52dp"
+    android:paddingStart="24dp"
     android:gravity="center_vertical"
     android:orientation="horizontal"
     android:baselineAligned="false"
     android:background="@drawable/root_item_background">
 
     <FrameLayout
-        android:layout_width="@dimen/icon_size"
+        android:layout_width="wrap_content"
         android:layout_height="@dimen/icon_size"
         android:duplicateParentState="true">
 
@@ -56,9 +56,7 @@
             android:singleLine="true"
             android:ellipsize="end"
             android:textAlignment="viewStart"
-            android:fontFamily="sans-serif-medium"
-            android:textSize="14sp"
-            android:textColor="@color/item_root_primary_text" />
+            android:textAppearance="@style/DrawerMenuPrimary" />
 
         <TextView
             android:id="@android:id/summary"
@@ -67,24 +65,27 @@
             android:singleLine="true"
             android:ellipsize="end"
             android:textAlignment="viewStart"
-            android:fontFamily="sans-serif-medium"
-            android:textSize="13sp"
-            android:textColor="@color/root_details_color" />
+            android:textAppearance="@style/DrawerMenuSecondary" />
 
     </LinearLayout>
 
+    <include layout="@layout/root_vertical_divider" />
+
     <FrameLayout
-        android:layout_width="@dimen/icon_size"
-        android:layout_height="@dimen/icon_size"
-        android:duplicateParentState="true">
+        android:id="@+id/action_icon_area"
+        android:layout_width="@dimen/button_touch_size"
+        android:layout_height="@dimen/button_touch_size"
+        android:paddingEnd="@dimen/grid_padding_horiz"
+        android:duplicateParentState="true"
+        android:visibility="gone">
 
         <ImageView
-            android:id="@+id/eject_icon"
-            android:layout_width="@dimen/root_icon_size"
+            android:id="@+id/action_icon"
+            android:focusable="false"
+            android:layout_width="@dimen/root_action_icon_size"
             android:layout_height="match_parent"
-            android:scaleType="centerInside"
-            android:contentDescription="@string/menu_eject_root"
-            android:visibility="gone" />
+            android:layout_gravity="center"
+            android:scaleType="centerInside"/>
 
     </FrameLayout>
 
diff --git a/res/layout/item_root_spacer.xml b/res/layout/item_root_spacer.xml
index ebe211c..16ecee7 100644
--- a/res/layout/item_root_spacer.xml
+++ b/res/layout/item_root_spacer.xml
@@ -17,6 +17,7 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:paddingStart="@dimen/root_spacer_padding"
     android:paddingTop="12dp"
     android:paddingBottom="12dp">
 
diff --git a/res/layout/item_subdir.xml b/res/layout/item_subdir.xml
index ffe4afe..c00b14b 100644
--- a/res/layout/item_subdir.xml
+++ b/res/layout/item_subdir.xml
@@ -32,7 +32,7 @@
         android:singleLine="true"
         android:ellipsize="end"
         android:textAlignment="viewStart"
-        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+        android:textAppearance="?android:attr/textAppearanceListItem"
         android:textColor="?android:attr/textColorPrimary" />
 
 </LinearLayout>
diff --git a/res/layout/item_subdir_title.xml b/res/layout/item_subdir_title.xml
index 8d0d807..6d71fca 100644
--- a/res/layout/item_subdir_title.xml
+++ b/res/layout/item_subdir_title.xml
@@ -30,5 +30,6 @@
         android:textAlignment="viewStart"
         android:drawablePadding="12dp"
         android:drawableRight="@drawable/ic_breadcrumb_arrow_down"
-        android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title" />
+        android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"
+        android:gravity="center_vertical"/>
 </LinearLayout>
diff --git a/res/layout/root_vertical_divider.xml b/res/layout/root_vertical_divider.xml
new file mode 100644
index 0000000..6b9c723
--- /dev/null
+++ b/res/layout/root_vertical_divider.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/vertical_divider"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:gravity="start|center_vertical"
+    android:orientation="horizontal"
+    android:paddingTop="@dimen/drawer_edge_width"
+    android:paddingBottom="@dimen/drawer_edge_width"
+    android:paddingStart="@dimen/grid_padding_horiz"
+    android:paddingEnd="@dimen/grid_padding_horiz"
+    android:visibility="gone">
+    <View
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        android:background="?android:attr/listDivider"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/search_chip_item.xml b/res/layout/search_chip_item.xml
new file mode 100644
index 0000000..cb67993
--- /dev/null
+++ b/res/layout/search_chip_item.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<com.google.android.material.chip.Chip
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:checkable="true"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginStart="@dimen/search_chip_spacing"
+    android:textAppearance="@style/SearchChipText"
+    android:textColor="@color/search_chip_text_color"
+    app:checkedIcon="@drawable/ic_check"
+    app:chipBackgroundColor="@color/search_chip_background_color"
+    app:chipCornerRadius="@dimen/search_chip_radius"
+    app:chipStrokeColor="@color/search_chip_stroke_color"
+    app:chipStrokeWidth="1dp"
+    app:iconStartPadding="@dimen/search_chip_icon_padding"
+    app:rippleColor="@color/search_chip_ripple_color"
+    app:chipMinTouchTargetSize="@dimen/button_touch_size"
+/>
\ No newline at end of file
diff --git a/res/layout/search_chip_row.xml b/res/layout/search_chip_row.xml
new file mode 100644
index 0000000..1375177
--- /dev/null
+++ b/res/layout/search_chip_row.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<HorizontalScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:overScrollMode="never"
+    android:scrollbars="none">
+    <LinearLayout
+        android:id="@+id/search_chip_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="@dimen/search_chip_spacing"/>
+</HorizontalScrollView>
\ No newline at end of file
diff --git a/res/layout/selection_demo_layout.xml b/res/layout/selection_demo_layout.xml
index c4ed360..9cee88d 100644
--- a/res/layout/selection_demo_layout.xml
+++ b/res/layout/selection_demo_layout.xml
@@ -19,16 +19,16 @@
        android:layout_height="match_parent"
        android:orientation="vertical">
 
-  <android.support.v7.widget.Toolbar
+  <androidx.appcompat.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
-     android:background="?attr/colorPrimary"
+     android:background="?android:attr/colorBackground"
      android:elevation="4dp"
      android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
      />
 
-  <android.support.v7.widget.RecyclerView
+  <androidx.recyclerview.widget.RecyclerView
       android:id="@+id/list"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
diff --git a/res/layout/sort_list_item.xml b/res/layout/sort_list_item.xml
new file mode 100644
index 0000000..c2f50c8
--- /dev/null
+++ b/res/layout/sort_list_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:id="@android:id/text1"
+                 android:layout_width="match_parent"
+                 android:layout_height="?android:attr/listPreferredItemHeightSmall"
+                 android:textAppearance="@style/SortList"
+                 android:gravity="center_vertical"
+                 android:checkMark="@drawable/list_checker"
+                 android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+                 android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
\ No newline at end of file
diff --git a/res/layout/table_key_value_row.xml b/res/layout/table_key_value_row.xml
index b45cda4..6a0b4be 100644
--- a/res/layout/table_key_value_row.xml
+++ b/res/layout/table_key_value_row.xml
@@ -19,20 +19,19 @@
     android:orientation="horizontal"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:paddingTop="10dp"
-    android:paddingBottom="10dp"
-    android:paddingStart="16dp"
-    android:paddingEnd="16dp">
+    android:paddingStart="30dp"
+    android:paddingEnd="30dp">
 
     <TextView
         android:id="@+id/table_row_key"
         android:layout_height="wrap_content"
         android:layout_width="0dp"
         android:layout_weight="1"
+        android:paddingTop="13dp"
+        android:paddingBottom="13dp"
         android:paddingEnd="5dp"
-        android:textColor="@android:color/black"
-        android:textSize="14sp"
-        android:textAlignment="viewStart">
+        android:textAlignment="viewStart"
+        android:textAppearance="?attr/textAppearanceSubtitle1">
     </TextView>
 
     <TextView
@@ -40,10 +39,12 @@
         android:layout_height="wrap_content"
         android:layout_width="0dp"
         android:layout_weight="1"
-        android:textColor="@color/inspector_value"
-        android:textSize="14sp"
+        android:paddingTop="13dp"
+        android:paddingBottom="13dp"
+        android:clickable="false"
         android:textIsSelectable="true"
-        android:textAlignment="viewStart">
+        android:textAlignment="viewStart"
+        android:textAppearance="@style/InspectorKeySubTitle">
     </TextView>
 
 </com.android.documentsui.inspector.KeyValueRow>
diff --git a/res/menu/action_mode_menu.xml b/res/menu/action_mode_menu.xml
index 1952285..f0ae09e 100644
--- a/res/menu/action_mode_menu.xml
+++ b/res/menu/action_mode_menu.xml
@@ -16,10 +16,6 @@
 
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:id="@+id/action_menu_open"
-        android:title="@string/menu_open"
-        android:showAsAction="always" />
-    <item
         android:id="@+id/action_menu_open_with"
         android:title="@string/menu_open_with"
         android:showAsAction="never" />
@@ -34,6 +30,14 @@
         android:title="@string/menu_delete"
         android:showAsAction="always" />
     <item
+        android:id="@+id/action_menu_sort"
+        android:title="@string/menu_sort"
+        android:showAsAction="never" />
+    <item
+        android:id="@+id/action_menu_select"
+        android:title="@string/menu_select"
+        android:showAsAction="always" />
+    <item
         android:id="@+id/action_menu_select_all"
         android:title="@string/menu_select_all"
         android:showAsAction="never" />
diff --git a/res/menu/activity.xml b/res/menu/activity.xml
index 0c1e68c..349aa93 100644
--- a/res/menu/activity.xml
+++ b/res/menu/activity.xml
@@ -14,7 +14,9 @@
      limitations under the License.
 -->
 
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
 <!-- showAsAction flag impacts the behavior of SearchView.
      When set to collapseActionView, collapsing SearchView to icon is the
      default behavior. It would fit UX, however after expanding SearchView is
@@ -27,10 +29,10 @@
         android:id="@+id/option_menu_search"
         android:title="@string/menu_search"
         android:icon="@drawable/ic_menu_search"
-        android:showAsAction="always"
-        android:actionViewClass="android.widget.SearchView"
         android:imeOptions="actionSearch"
-        android:visible="false" />
+        android:visible="false"
+        app:showAsAction="always|collapseActionView"
+        app:actionViewClass="androidx.appcompat.widget.SearchView"/>
 <!-- This group is being hidden when searching is in full bar mode-->
     <group android:id="@+id/group_hide_when_searching">
         <item
@@ -38,49 +40,43 @@
             android:title="Debug"
             android:icon="@drawable/ic_debug_menu"
             android:visible="false"
-            android:showAsAction="always" />
-        <item
-            android:id="@+id/option_menu_grid"
-            android:title="@string/menu_grid"
-            android:icon="@drawable/ic_menu_view_grid"
-            android:showAsAction="always" />
-        <item
-            android:id="@+id/option_menu_list"
-            android:title="@string/menu_list"
-            android:icon="@drawable/ic_menu_view_list"
-            android:showAsAction="always" />
+            app:showAsAction="always"/>
         <item
             android:id="@+id/option_menu_new_window"
             android:title="@string/menu_new_window"
             android:alphabeticShortcut="n"
-            android:showAsAction="never"
-            android:visible="false" />
+            android:visible="false"
+            app:showAsAction="never"/>
         <item
             android:id="@+id/option_menu_create_dir"
             android:title="@string/menu_create_dir"
-            android:icon="@drawable/ic_menu_new_folder"
             android:alphabeticShortcut="e"
+            android:visible="false"
+            app:showAsAction="never"/>
+        <item
+            android:id="@+id/option_menu_sort"
+            android:title="@string/menu_sort"
             android:showAsAction="never"
             android:visible="false" />
         <item
             android:id="@+id/option_menu_select_all"
             android:title="@string/menu_select_all"
             android:alphabeticShortcut="a"
-            android:showAsAction="never"
-            android:visible="false" />
+            android:visible="false"
+            app:showAsAction="never"/>
         <item
             android:id="@+id/option_menu_advanced"
-            android:showAsAction="never"
-            android:visible="false" />
+            android:visible="false"
+            app:showAsAction="never"/>
         <item
             android:id="@+id/option_menu_settings"
             android:title="@string/menu_settings"
-            android:showAsAction="never"
-            android:visible="false" />
+            android:visible="false"
+            app:showAsAction="never"/>
        <item
            android:id="@+id/option_menu_inspect"
            android:title="@string/menu_inspect"
-           android:showAsAction="never"
-           android:visible="false" />
+           android:visible="false"
+           app:showAsAction="never"/>
     </group>
 </menu>
diff --git a/res/menu/sub_menu.xml b/res/menu/sub_menu.xml
new file mode 100644
index 0000000..73a97dc
--- /dev/null
+++ b/res/menu/sub_menu.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<menu
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/sub_menu_grid"
+        android:title="@string/menu_grid"
+        android:icon="@drawable/ic_menu_view_grid"
+        app:showAsAction="always"/>
+    <item
+        android:id="@+id/sub_menu_list"
+        android:title="@string/menu_list"
+        android:icon="@drawable/ic_menu_view_list"
+        app:showAsAction="always"/>
+</menu>
\ No newline at end of file
diff --git a/res/values-af/config.xml b/res/values-af/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-af/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4eb5f41..62932cb 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Deel"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Vee uit"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Kies almal"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Kies"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Rangskik volgens …"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopieer na …"</string>
     <string name="menu_move" msgid="2310760789561129882">"Skuif na …"</string>
     <string name="menu_compress" msgid="37539111904724188">"Pers saam"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipe"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Grootte"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Gewysig"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Lêernaam (A tot Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Soort (A tot Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Grootte (kleinste eerste)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Gewysig (oudste eerste)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Lêernaam (Z tot A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Soort (Z tot A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Grootte (grootste eerste)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Gewysig (nuutste eerste)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Rangskik volgens"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Gerangskik volgens <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Aantal items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stygend"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Dalend"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Maak <xliff:g id="APPNAME">%1$s</xliff:g> oop"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Wys wortels"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Versteek wortels"</string>
     <string name="save_error" msgid="8631128801982095782">"Kon nie dokument stoor nie"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Vee tans <xliff:g id="COUNT_0">%1$d</xliff:g> item uit.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Ontdoen"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Maak tans gereed om te kopieer …"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Berei tans voor om saam te pers …"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Maak tans gereed om te onttrek …"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Maak tans gereed om te skuif …"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Maak tans gereed om uit te vee …"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Berei tans voor …"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Berei tans voor …"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Berei tans voor …"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Berei tans voor …"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Berei tans voor …"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> items nie kopieer nie</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot jou data, insluitend foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Moenie weer vra nie"</string>
     <string name="allow" msgid="1275746941353040309">"Laat toe"</string>
     <string name="deny" msgid="5127201668078153379">"Weier"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"argief<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Skryf oor <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Gaan op die agtergrond voort"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gekies</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gekies</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Onlangse lêers op foon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Lêers op foon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> op foon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Lêers op <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Lêers vanaf <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Lêers vanaf <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Onlangse prente op foon"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Prente op foon"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Prente op <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Prente vanaf <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Prente vanaf <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Prente"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Oudio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video\'s"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumente"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Vouernaam"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nuwe naam"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Voorbeskou die lêer <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Blaai deur lêers in ander programme"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anoniem"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Gee toegang tot \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Gee toegang tot \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" op \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Dit sal \"<xliff:g id="APPNAME">%1$s</xliff:g>\" volle toegang gee tot alle lêers wat tans onder hierdie ligging geberg word, asook enige toekomstige inhoud wat hier geberg word."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Deursoek hierdie foon"</string>
 </resources>
diff --git a/res/values-am/config.xml b/res/values-am/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-am/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 1cffb23..5960e11 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"አጋራ"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ሰርዝ"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"ሁሉንም ምረጥ"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ይምረጡ"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ደርድር በ..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"ቅዳ ወደ…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ውሰድ ወደ…"</string>
     <string name="menu_compress" msgid="37539111904724188">"ጭመቅ"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ዓይነት"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"መጠን"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"የተቀየረበት ጊዜ"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"የፋይል ስም (ሀ እስከ ፐ)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"አይነት (ሀ እስከ ፐ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"መጠን (ትንሹ መጀመሪያ)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ተቀይሯል (የድሮው መጀመሪያ)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"የፋይል ስም (ፐ እስከ ሀ)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"አይነት (ፐ እስከ ሀ)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"መጠን (ትልቁ መጀመሪያ)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ተቀይሯል (አዲሱ መጀመሪያ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ደርድር በ"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"በ<xliff:g id="LABEL">%s</xliff:g> የተደረደረ"</string>
     <string name="directory_items" msgid="6645621978998614003">"የንጥሎች ብዛት"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ሽቅብታ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"አቆልቋይ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g>ን ክፈት"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ስሮችን አሳይ"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ስሮችን ደብቅ"</string>
     <string name="save_error" msgid="8631128801982095782">"ሰነድን ማስቀመጥ አልተሳካም"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎችን በመሰረዝ ላይ።</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"ቀልብስ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"ለመቅዳት በመዘጋጀት ላይ…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"ለመጭመቅ በመዘጋጀት ላይ…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"ሰርስሮ ለማውጣት በማዘጋጀት ላይ…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ለመውሰድ በመዘጋጀት ላይ…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ለመሰረዝ በመዘጋጀት ላይ…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"በማዘጋጀት ላይ..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"በማዘጋጀት ላይ..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"በማዘጋጀት ላይ..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"በማዘጋጀት ላይ..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"በማዘጋጀት ላይ..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎችን መቅዳት አልተቻለም</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> በ<xliff:g id="STORAGE"><i>^3</i></xliff:g> ላይ የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መዳረሻ ይሰጠው?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጠው?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"በ<xliff:g id="STORAGE"><i>^2</i></xliff:g> ላይ ያሉትን ፎቶዎች እና ቪዲዮዎች ጨምሮ የውሂብዎ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጥ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ዳግም አትጠይቅ"</string>
     <string name="allow" msgid="1275746941353040309">"ፍቀድ"</string>
     <string name="deny" msgid="5127201668078153379">"ከልክል"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"ማህደር<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ይተካ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"በበስተጀርባ ውስጥ ቀጥል"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጧል</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"በስልክ ላይ የቅርብ ጊዜ ፋይሎች"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"በስልክ ላይ ያሉ ፋይሎች"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"በስልክ ላይ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"በ<xliff:g id="DEVICE">%1$s</xliff:g> ላይ ያሉ ፋይሎች"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"ከ<xliff:g id="LABEL">%1$s</xliff:g> የመጡ ፋይሎች"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"ከ<xliff:g id="LABEL">%1$s</xliff:g> የመጡ ፋይሎች / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"በስልክ ላይ ያሉ የቅርብ ጊዜ ምስሎች"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"በስልኩ ላይ ያሉ ምስሎች"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"በ<xliff:g id="DEVICE">%1$s</xliff:g> ላይ ያሉ ምስሎች"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"የ<xliff:g id="LABEL">%1$s</xliff:g> ምስሎች"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"ምስሎች ከ<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ምስሎች"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ኦዲዮ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ቪዲዮዎች"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ሰነዶች"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"የአቃፊ ስም"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"አዲስ ስም"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ፋይሉን በቅድመ እይታ ይመልከቱ"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ፋይሎችን በሌሎች መተግበሪያዎች ውስጥ ያስሱ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ስም-አልባ"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"የ«<xliff:g id="DIRECTORY">%1$s</xliff:g>» መዳረሻን ፍቀድ"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"በ«<xliff:g id="ROOT">%2$s</xliff:g>» ላይ የ«<xliff:g id="DIRECTORY">%1$s</xliff:g>» መዳረሻ ይፈቀድ?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"«<xliff:g id="APPNAME">%1$s</xliff:g>» በአሁኑ ጊዜ በዚህ ቦታ ላይ የተከማቹ እና ወደፊት በዚህ ላይ የሚከማቹ ማናቸውም ሁሉም ፋይሎች ሙሉ መዳረሻ እንዲኖረው ያስችላል።"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ይህን ስልክ ይፈልጉ"</string>
 </resources>
diff --git a/res/values-ar/config.xml b/res/values-ar/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ar/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 4199682..1117399 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"مشاركة"</string>
     <string name="menu_delete" msgid="1022254131543256626">"حذف"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"تحديد الكل"</string>
+    <string name="menu_select" msgid="1366061076507142387">"اختيار"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ترتيب حسب..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"نسخ إلى…"</string>
     <string name="menu_move" msgid="2310760789561129882">"نقل إلى..."</string>
     <string name="menu_compress" msgid="37539111904724188">"ضغط"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"النوع"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"الحجم"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"آخر تعديل"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"اسم الملف (من الألف للياء)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"النوع (من الألف إلى الياء)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"الحجم (الأصغر أولاً)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"تواريخ معدلة (الأقدم أولاً)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"اسم الملف (من الياء للألف)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"النوع (من الياء إلى الألف)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"الحجم (الأكبر أولاً)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"تواريخ معدلة (الأحدث أولاً)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ترتيب بحسب"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"الترتيب بحسب <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"عدد العناصر"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"تصاعدي"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"تنازلي"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"فتح <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"عرض الجذور"</string>
     <string name="drawer_close" msgid="4263880768630848848">"إخفاء الجذور"</string>
     <string name="save_error" msgid="8631128801982095782">"تعذّر حفظ المستند"</string>
@@ -132,11 +145,11 @@
       <item quantity="one">جارٍ حذف ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>).</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"تراجع"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"جارٍ التحضير للنسخ ..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"جارٍ التحضير للضغط…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"جارٍ الإعداد للاستخلاص…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"جارٍ التحضير للنقل…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"جارٍ الإعداد للحذف…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"جارٍ التحضير..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"جارٍ التحضير..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"جارٍ التحضير..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"جارٍ التحضير..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"جارٍ التحضير..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="zero">تعذَّر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملف</item>
@@ -235,8 +248,7 @@
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"تم تحويل بعض الملفات"</string>
     <string name="open_external_dialog_request" msgid="8173558471322861268">"هل تريد منح التطبيق <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى الدليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> على <xliff:g id="STORAGE"><i>^3</i></xliff:g>؟"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى دليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>؟"</string>
-    <string name="open_external_dialog_root_request" msgid="6776729293982633">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى بياناتك، بما في ذلك الصور ومقاطع الفيديو على <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"عدم السؤال مرة أخرى"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى بياناتك، بما في ذلك الصور والفيديوهات على <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
     <string name="allow" msgid="1275746941353040309">"السماح"</string>
     <string name="deny" msgid="5127201668078153379">"رفض"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -290,4 +302,37 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"أرشيف<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"هل تريد استبدال <xliff:g id="NAME">%1$s</xliff:g>؟"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"المتابعة في الخلفية"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="zero">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="two">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="few">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="many">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">تم اختيار <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"أحدث الملفات على الهاتف"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"الملفات على الهاتف"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> على الهاتف"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"ملفات على <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"ملفات من <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"ملفات من <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"أحدث الصور على الهاتف"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"الصور على الهاتف"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"الصور على <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"الصور من <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"الصور من <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"الصور"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"الصوت"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"الفيديوهات"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"المستندات"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"اسم المجلد"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"اسم جديد"</string>
+    <string name="preview_file" msgid="4056622696305432343">"معاينة الملف <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"تصفّح الملفات في تطبيقات أخرى"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"مجهول"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"السماح بالوصول إلى \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"يؤدي ذلك إلى السماح لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" بالحصول على إمكانية الدخول الكاملة إلى جميع الملفات المخزَّنة حاليًا ضِمنَ هذا الموقع وإلى أيّ محتوى يُخزَّن هنا في المستقبل."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"البحث في هذا الهاتف"</string>
 </resources>
diff --git a/res/values-as/inspector_strings.xml b/res/values-as/inspector_strings.xml
new file mode 100644
index 0000000..6d5f90e
--- /dev/null
+++ b/res/values-as/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"তথ্য"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ফাইলৰ তথ্য ল\'ড কৰিবপৰা নগ\'ল"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ডিবাগ তথ্য (বিকাশকৰ্তা মাত্ৰ)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ৰ\' মেটাডেটা: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"মিডিয়াৰ সবিশেষ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"এইধৰণৰ ফাইল ই খুলিব পাৰে"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ই এই ফাইলটো যোগান ধৰিছে"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"বাছনি কৰা হোৱা নাই"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"অজ্ঞাত"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"দীঘ-প্ৰস্থ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>মে.পি."</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"স্থানাংক"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"উচ্চতা"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"কেমেৰা"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"এপাৰচ্চাৰ"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"শ্বাটাৰৰ বেগ"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"কালদৈৰ্ঘ্য"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"তোলাৰ সময়"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ফ\'কেল দৈৰ্ঘ্য"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>মি.মি."</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"আইএছঅ\' সমতুল্য"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"আইএছঅ\' <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"শিল্পী"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"সুৰকাৰ"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"এলবাম"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"অৱস্থান"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ষ্ট্ৰীমৰ প্ৰকাৰ"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ডিবাগ ফাইলৰ আকাৰ (বাইট)"</string>
+</resources>
diff --git a/res/values-as/mimes.xml b/res/values-as/mimes.xml
new file mode 100644
index 0000000..d5b4102
--- /dev/null
+++ b/res/values-as/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ফাইল"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ফাইল"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"চিত্ৰ"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> চিত্ৰ"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"অডিঅ’"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> অডিঅ\'"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ভিডিঅ\'"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ভিডিঅ\'"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> আৰ্কাইভ"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android এপ্লিকেশ্বন"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"সাধাৰণ পাঠ"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML নথি"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF নথি"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word নথি"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"PowerPoint উপস্থাপন"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel স্প্ৰেডশ্বীট"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google নথি"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google স্প্ৰেডশ্বীট"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google উপস্থাপন"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google অংকন"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google তালিকা"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ফৰ্ম"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google মেপ"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google ছাইট"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ফ\'ল্ডাৰ"</string>
+</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 4a93e16..03985a3 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -16,144 +16,94 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="files_label" msgid="771781190045103748">"ফাইলবোৰ"</string>
-    <!-- no translation found for downloads_label (5462789470049501103) -->
-    <skip />
+    <string name="files_label" msgid="771781190045103748">"ফাইল"</string>
+    <string name="downloads_label" msgid="5462789470049501103">"ডাউনল\'ডসমূহ"</string>
     <!-- no translation found for app_label (8089292432455111409) -->
     <skip />
     <!-- no translation found for launcher_label (799410258349837668) -->
     <skip />
-    <!-- no translation found for title_open (3165686459158020921) -->
-    <skip />
-    <!-- no translation found for title_save (4384490653102710025) -->
-    <skip />
-    <!-- no translation found for menu_create_dir (2413624798689091042) -->
-    <skip />
-    <!-- no translation found for menu_grid (1453636521731880680) -->
-    <skip />
-    <!-- no translation found for menu_list (6714267452146410402) -->
-    <skip />
-    <!-- no translation found for menu_search (1876699106790719849) -->
-    <skip />
-    <!-- no translation found for menu_settings (6520844520117939047) -->
-    <skip />
-    <!-- no translation found for menu_open (9092138100049759315) -->
-    <skip />
-    <!-- no translation found for menu_open_with (5507647065467520229) -->
-    <skip />
-    <!-- no translation found for menu_open_in_new_window (6686563636123311276) -->
-    <skip />
-    <!-- no translation found for menu_save (5195367497138965168) -->
-    <skip />
-    <!-- no translation found for menu_share (4307140947108068356) -->
-    <skip />
-    <!-- no translation found for menu_delete (1022254131543256626) -->
-    <skip />
-    <!-- no translation found for menu_select_all (7600576812185570403) -->
-    <skip />
-    <!-- no translation found for menu_copy (7404820171352314754) -->
-    <skip />
-    <!-- no translation found for menu_move (2310760789561129882) -->
-    <skip />
+    <string name="title_open" msgid="3165686459158020921">"ইয়াৰ পৰা খোলক"</string>
+    <string name="title_save" msgid="4384490653102710025">"ইয়াত ছেভ কৰক"</string>
+    <string name="menu_create_dir" msgid="2413624798689091042">"নতুন ফ\'ল্ডাৰ"</string>
+    <string name="menu_grid" msgid="1453636521731880680">"গ্ৰিড হিচাপে চোৱাৰ সুবিধা"</string>
+    <string name="menu_list" msgid="6714267452146410402">"সূচী অনুসৰি চোৱাৰ সুবিধা"</string>
+    <string name="menu_search" msgid="1876699106790719849">"অনুসন্ধান কৰক"</string>
+    <string name="menu_settings" msgid="6520844520117939047">"সঞ্চয়াগাৰৰ ছেটিংসমূহ"</string>
+    <string name="menu_open" msgid="9092138100049759315">"খোলক"</string>
+    <string name="menu_open_with" msgid="5507647065467520229">"ইয়াৰ জৰিয়তে খোলক"</string>
+    <string name="menu_open_in_new_window" msgid="6686563636123311276">"নতুন ৱিণ্ড\'ত খোলক"</string>
+    <string name="menu_save" msgid="5195367497138965168">"ছেভ কৰক"</string>
+    <string name="menu_share" msgid="4307140947108068356">"শ্বেয়াৰ কৰক"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"মচক"</string>
+    <string name="menu_select_all" msgid="7600576812185570403">"সকলো বাছনি কৰক"</string>
+    <string name="menu_select" msgid="1366061076507142387">"বাছনি কৰক"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"এই অনুসৰি সজাওক..."</string>
+    <string name="menu_copy" msgid="7404820171352314754">"ইয়াত প্ৰতিলিপি কৰক…"</string>
+    <string name="menu_move" msgid="2310760789561129882">"ইয়ালৈ স্থানান্তৰ কৰক…"</string>
     <string name="menu_compress" msgid="37539111904724188">"সংকুচিত কৰক"</string>
     <string name="menu_extract" msgid="8171946945982532262">"ইয়ালৈ আহৰণ কৰক…"</string>
-    <!-- no translation found for menu_rename (1883113442688817554) -->
-    <skip />
-    <!-- no translation found for menu_inspect (7279855349299446224) -->
-    <skip />
+    <string name="menu_rename" msgid="1883113442688817554">"নতুন নাম দিয়ক"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"তথ্য পাওক"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>ত চাওক"</string>
-    <!-- no translation found for menu_new_window (2947837751796109126) -->
-    <skip />
-    <!-- no translation found for menu_cut_to_clipboard (2878752142015026229) -->
-    <skip />
-    <!-- no translation found for menu_copy_to_clipboard (5064081159073330776) -->
-    <skip />
-    <!-- no translation found for menu_paste_from_clipboard (360947260414135827) -->
-    <skip />
-    <!-- no translation found for menu_paste_into_folder (8000644546983240101) -->
-    <skip />
-    <!-- no translation found for menu_advanced_show (7558626506462906726) -->
-    <skip />
-    <!-- no translation found for menu_advanced_hide (6488381508009246334) -->
-    <skip />
-    <!-- no translation found for button_select (240863497069321364) -->
-    <skip />
-    <!-- no translation found for button_copy (8219059853840996027) -->
-    <skip />
+    <string name="menu_new_window" msgid="2947837751796109126">"নতুন ৱিণ্ড\'"</string>
+    <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"কাট কৰক"</string>
+    <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"প্ৰতিলিপি কৰক"</string>
+    <string name="menu_paste_from_clipboard" msgid="360947260414135827">"পেইষ্ট কৰক"</string>
+    <string name="menu_paste_into_folder" msgid="8000644546983240101">"ফ\'ল্ডাৰত পেইষ্ট কৰক"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"আভ্যন্তৰীণ সঞ্চয়াগাৰ দেখুৱাওক"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"আভ্যন্তৰীণ সঞ্চয়াগাৰ লুকুৱাওক"</string>
+    <string name="button_select" msgid="240863497069321364">"বাছনি কৰক"</string>
+    <string name="button_copy" msgid="8219059853840996027">"প্ৰতিলিপি কৰক"</string>
     <string name="button_compress" msgid="8951561310857223966">"সংকুচিত কৰক"</string>
     <string name="button_extract" msgid="1038674453689912247">"আহৰণ কৰক"</string>
-    <!-- no translation found for button_move (8596460499325291272) -->
-    <skip />
-    <!-- no translation found for button_dismiss (7235249361023803349) -->
-    <skip />
-    <!-- no translation found for button_retry (4011461781916631389) -->
-    <skip />
-    <!-- no translation found for button_clear (5412304437764369441) -->
-    <skip />
-    <!-- no translation found for button_show_provider (6905880493806292753) -->
-    <skip />
-    <!-- no translation found for not_sorted (7813496644889115530) -->
-    <skip />
-    <!-- no translation found for sort_dimension_name (6325591541414177579) -->
-    <skip />
-    <!-- no translation found for sort_dimension_summary (7724534446881397860) -->
-    <skip />
-    <!-- no translation found for sort_dimension_file_type (5779709622922085381) -->
-    <skip />
-    <!-- no translation found for sort_dimension_size (2190547351159472884) -->
-    <skip />
-    <!-- no translation found for sort_dimension_date (4231005651895254033) -->
-    <skip />
-    <!-- no translation found for directory_items (6645621978998614003) -->
-    <skip />
-    <!-- no translation found for sort_direction_ascending (5882787683763248102) -->
-    <skip />
-    <!-- no translation found for sort_direction_descending (1729187589765894076) -->
-    <skip />
-    <!-- no translation found for drawer_open (8071673398187261741) -->
-    <skip />
-    <!-- no translation found for drawer_close (4263880768630848848) -->
-    <skip />
-    <!-- no translation found for save_error (8631128801982095782) -->
-    <skip />
-    <!-- no translation found for create_error (3092144450044861994) -->
-    <skip />
-    <!-- no translation found for query_error (6625421453613879336) -->
-    <skip />
-    <!-- no translation found for root_recent (1080156975424341623) -->
-    <skip />
-    <!-- no translation found for root_available_bytes (8269870862691408864) -->
-    <skip />
-    <!-- no translation found for root_type_service (6521366147466512289) -->
-    <skip />
-    <!-- no translation found for root_type_shortcut (6059343175525442279) -->
-    <skip />
-    <!-- no translation found for root_type_device (1713604128005476585) -->
-    <skip />
-    <!-- no translation found for root_type_apps (8646073235029886342) -->
-    <skip />
-    <!-- no translation found for empty (5300254272613103004) -->
-    <skip />
-    <!-- no translation found for no_results (2371026325236359209) -->
-    <skip />
-    <!-- no translation found for toast_no_application (7555319548595113121) -->
-    <skip />
+    <string name="button_move" msgid="8596460499325291272">"স্থানান্তৰ কৰক"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"প্ৰত্যাখ্যান কৰক"</string>
+    <string name="button_retry" msgid="4011461781916631389">"আকৌ চেষ্টা কৰক"</string>
+    <string name="button_clear" msgid="5412304437764369441">"মচক"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"যোগানকাৰীত দেখুৱাওক"</string>
+    <string name="not_sorted" msgid="7813496644889115530">"ক্ৰমবদ্ধ কৰা হোৱা নাই"</string>
+    <string name="sort_dimension_name" msgid="6325591541414177579">"নাম"</string>
+    <string name="sort_dimension_summary" msgid="7724534446881397860">"সাৰাংশ"</string>
+    <string name="sort_dimension_file_type" msgid="5779709622922085381">"প্রকাৰ"</string>
+    <string name="sort_dimension_size" msgid="2190547351159472884">"আকাৰ"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"সংশোধন কৰা হ’ল"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ফাইলৰ নাম (Aৰ পৰা Zলৈ)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"প্ৰকাৰ (Aৰ পৰা Zলৈ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"আকাৰ (সৰুবোৰ প্ৰথমে)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"সংশোধিত (পুৰণিবোৰ প্ৰথমে)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ফাইলৰ নাম (Zৰ পৰা Aলৈ)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"প্ৰকাৰ (Zৰ পৰা Aলৈ)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"আকাৰ (ডাঙৰবোৰ প্ৰথমে)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"সংশোধিত (নতুনবোৰ প্ৰথমে)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"এই অনুসৰি সজাওক"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> অনুসৰি সজোৱা হৈছে"</string>
+    <string name="directory_items" msgid="6645621978998614003">"সমলৰ সংখ্যা"</string>
+    <string name="sort_direction_ascending" msgid="5882787683763248102">"ঊৰ্ধ্বক্ৰমিক"</string>
+    <string name="sort_direction_descending" msgid="1729187589765894076">"অধঃক্ৰমিক"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
+    <string name="drawer_open" msgid="8071673398187261741">"ৰুটসমূহ দেখুৱাওক"</string>
+    <string name="drawer_close" msgid="4263880768630848848">"ৰুটসমূহ লুকুৱাওক"</string>
+    <string name="save_error" msgid="8631128801982095782">"নথি-পত্ৰ ছেভ কৰিব পৰা নগ\'ল"</string>
+    <string name="create_error" msgid="3092144450044861994">"ফ\'ল্ডাৰ সৃষ্টি কৰিব পৰা নগ\'ল"</string>
+    <string name="query_error" msgid="6625421453613879336">"এই মুহূৰ্তত সমল ল\'ড কৰিব নোৱাৰি"</string>
+    <string name="root_recent" msgid="1080156975424341623">"শেহতীয়া"</string>
+    <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> খালী আছে"</string>
+    <string name="root_type_service" msgid="6521366147466512289">"সঞ্চয়াগাৰৰ সেৱাসমূহ"</string>
+    <string name="root_type_shortcut" msgid="6059343175525442279">"শ্বৰ্টকাটসমূহ"</string>
+    <string name="root_type_device" msgid="1713604128005476585">"ডিভাইচসমূহ"</string>
+    <string name="root_type_apps" msgid="8646073235029886342">"অধিক এপ্"</string>
+    <string name="empty" msgid="5300254272613103004">"কোনো বস্তু নাই"</string>
+    <string name="no_results" msgid="2371026325236359209">"%1$s ত কোনো মিল পোৱা নগ\'ল"</string>
+    <string name="toast_no_application" msgid="7555319548595113121">"ফাইল খুলিব পৰা নাই"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"আৰ্কাইভত থকা ফাইলবোৰ খুলিব নোৱাৰি"</string>
-    <!-- no translation found for toast_failed_delete (3453846588205817591) -->
-    <skip />
-    <!-- no translation found for share_via (8725082736005677161) -->
-    <skip />
-    <!-- no translation found for copy_notification_title (52256435625098456) -->
-    <skip />
+    <string name="toast_failed_delete" msgid="3453846588205817591">"কিছুমান নথি মচিব পৰা নগ\'ল"</string>
+    <string name="share_via" msgid="8725082736005677161">"ইয়াৰ জৰিয়তে শ্বেয়াৰ কৰক"</string>
+    <string name="copy_notification_title" msgid="52256435625098456">"ফাইলসমূহৰ প্ৰতিলিপি কৰি থকা হৈছে"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"ফাইলবোৰ সংকুচিত কৰি থকা হৈছে"</string>
-    <!-- no translation found for extract_notification_title (5067393961754430469) -->
-    <skip />
-    <!-- no translation found for move_notification_title (3173424987049347605) -->
-    <skip />
-    <!-- no translation found for delete_notification_title (2512757431856830792) -->
-    <skip />
-    <!-- no translation found for copy_remaining (5390517377265177727) -->
-    <skip />
+    <string name="extract_notification_title" msgid="5067393961754430469">"ফাইল আহৰণ কৰি থকা হৈছে"</string>
+    <string name="move_notification_title" msgid="3173424987049347605">"ফাইল আঁতৰাই থকা হৈছে"</string>
+    <string name="delete_notification_title" msgid="2512757431856830792">"ফাইলসমূহ মচি থকা হৈছে"</string>
+    <string name="copy_remaining" msgid="5390517377265177727">"<xliff:g id="DURATION">%s</xliff:g> মিনিট বাকী আছে"</string>
     <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু প্ৰতিলিপি কৰি থকা হৈছে।</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু প্ৰতিলিপি কৰি থকা হৈছে।</item>
@@ -174,18 +124,13 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু মচি থকা হৈছে।</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু মচি থকা হৈছে।</item>
     </plurals>
-    <!-- no translation found for undo (2902438994196400565) -->
-    <skip />
-    <!-- no translation found for copy_preparing (5326063807006898223) -->
-    <skip />
-    <string name="compress_preparing" msgid="6650018601382062672">"সংকুচিত কৰিবলৈ প্ৰস্তুত কৰি থকা হৈছে…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"আহৰণ কৰিবলৈ সাজু কৰি থকা হৈছে…"</string>
-    <!-- no translation found for move_preparing (8742573245485449429) -->
-    <skip />
-    <!-- no translation found for delete_preparing (6513863752916028147) -->
-    <skip />
-    <!-- no translation found for delete_progress (2627631054702306423) -->
-    <skip />
+    <string name="undo" msgid="2902438994196400565">"আনডু কৰক"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"সাজু কৰি থকা হৈছে…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"সাজু কৰি থকা হৈছে…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"সাজু কৰি থকা হৈছে…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"সাজু কৰি থকা হৈছে…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"সাজু কৰি থকা হৈছে…"</string>
+    <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু প্ৰতিলিপি কৰিব পৰা নগ\'ল</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু প্ৰতিলিপি কৰিব পৰা নগ\'ল</item>
@@ -202,10 +147,8 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু মচিব পৰা নগ\'ল</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু মচিব পৰা নগ\'ল</item>
     </plurals>
-    <!-- no translation found for notification_touch_for_details (2385563502445129570) -->
-    <skip />
-    <!-- no translation found for close (905969391788869975) -->
-    <skip />
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"সবিশেষ চাবলৈ টিপক"</string>
+    <string name="close" msgid="905969391788869975">"বন্ধ কৰক"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
       <item quantity="one">এই ফাইলবোৰ প্ৰতিলিপি কৰা নহ\'ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
       <item quantity="other">এই ফাইলবোৰ প্ৰতিলিপি কৰা নহ\'ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
@@ -227,53 +170,80 @@
       <item quantity="other">এই ফাইলবোৰ মচা নহ\'ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
-      <item quantity="one">এই ফাইলবোৰ অন্য এটা ফৰ্মেটলৈ সলনি কৰা হ\'ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
-      <item quantity="other">এই ফাইলবোৰ অন্য এটা ফৰ্মেটলৈ সলনি কৰা হ\'ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">এই ফাইলবোৰ অন্য এটা ফৰ্মেটলৈ সলনি কৰা হ’ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="other">এই ফাইলবোৰ অন্য এটা ফৰ্মেটলৈ সলনি কৰা হ’ল: <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু ক্লিপব\'ৰ্ডত প্ৰতিলিপি কৰা হ\'ল।</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু ক্লিপব\'ৰ্ডত প্ৰতিলিপি কৰা হ\'ল।</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু ক্লিপব\'ৰ্ডত প্ৰতিলিপি কৰা হ’ল।</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু ক্লিপব\'ৰ্ডত প্ৰতিলিপি কৰা হ’ল।</item>
     </plurals>
     <string name="file_operation_rejected" msgid="4301554203329008794">"ফাইলত কাৰ্য কৰিব নোৱাৰি।"</string>
     <string name="file_operation_error" msgid="2234357335716533795">"ফাইলত কাৰ্য কৰিব পৰা নগ\'ল।"</string>
-    <!-- no translation found for rename_error (6700093173508118635) -->
-    <skip />
-    <!-- no translation found for menu_eject_root (9215040039374893613) -->
-    <skip />
-    <!-- no translation found for notification_copy_files_converted_title (6916768494891833365) -->
-    <skip />
-    <!-- no translation found for open_external_dialog_request (8173558471322861268) -->
-    <skip />
-    <!-- no translation found for open_external_dialog_request_primary_volume (2240992164087948176) -->
-    <skip />
-    <!-- no translation found for open_external_dialog_root_request (6776729293982633) -->
-    <skip />
-    <!-- no translation found for never_ask_again (525908236522201138) -->
-    <skip />
-    <!-- no translation found for allow (1275746941353040309) -->
-    <skip />
-    <!-- no translation found for deny (5127201668078153379) -->
-    <skip />
-    <!-- no translation found for elements_selected (4448165978637163692) -->
-    <!-- no translation found for elements_dragged (5932571296037626279) -->
-    <!-- no translation found for delete_filename_confirmation_message (8338069763240613258) -->
-    <skip />
-    <!-- no translation found for delete_foldername_confirmation_message (9084085260877704140) -->
-    <skip />
-    <!-- no translation found for delete_files_confirmation_message (4866664063250034142) -->
-    <!-- no translation found for delete_folders_confirmation_message (1028946402799686388) -->
-    <!-- no translation found for delete_items_confirmation_message (7285090426511028179) -->
+    <string name="rename_error" msgid="6700093173508118635">"নথিৰ নাম সলনি কৰিব পৰা নগ\'ল"</string>
+    <string name="menu_eject_root" msgid="9215040039374893613">"বাহিৰলৈ উলিয়াওক"</string>
+    <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"কিছুমান ফাইল ৰূপান্তৰ কৰা হ’ল"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>ক <xliff:g id="STORAGE"><i>^3</i></xliff:g>ৰ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> চাবলৈ অনুমতি দিবনে?"</string>
+    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>ক <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> চাবলৈ অনুমতি দিবনে?"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>ক <xliff:g id="STORAGE"><i>^2</i></xliff:g>ত থকা ফট\' আৰু ভিডিঅ\'সমূহকে ধৰি আপোনাৰ ডেটা চাবলৈ অনুমতি দিবনে?"</string>
+    <string name="allow" msgid="1275746941353040309">"অনুমতি দিয়ক"</string>
+    <string name="deny" msgid="5127201668078153379">"অস্বীকাৰ কৰক"</string>
+    <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item>
+    </plurals>
+    <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু</item>
+    </plurals>
+    <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"\"<xliff:g id="NAME">%1$s</xliff:g>\"ক মচিবনে?"</string>
+    <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ফ\'ল্ডাৰ আৰু ইয়াৰ সমলসমূহ মচিবনে?"</string>
+    <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা ফাইল মচিবনে?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা ফাইল মচিবনে?</item>
+    </plurals>
+    <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা ফ\'ল্ডাৰ আৰু ইয়াৰ সমলসমূহ মচিবনে?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা ফ\'ল্ডাৰ আৰু ইয়াৰ সমলসমূহ মচিবনে?</item>
+    </plurals>
+    <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু মচিবনে?</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বস্তু মচিবনে?</item>
+    </plurals>
     <string name="images_shortcut_label" msgid="2545168016070493574">"প্ৰতিচ্ছবিবোৰ"</string>
     <string name="archive_loading_failed" msgid="7243436722828766996">"ব্ৰাউজ কৰিবলৈ আৰ্কাইভ খুলিব পৰা নগ\'ল। ফাইলটো হয় ব্যৱহাৰযোগ্য হৈ থকা নাই বা ব্যৱহাৰ কৰিব পৰা ফৰ্মেটত নাই।"</string>
     <string name="name_conflict" msgid="28407269328862986">"এই নামৰ অইন এটা ফাইল ইতিমধ্যে আছে।"</string>
-    <!-- no translation found for authentication_required (8030880723643436099) -->
-    <skip />
-    <!-- no translation found for cant_display_content (8633226333229417237) -->
-    <skip />
-    <!-- no translation found for sign_in (6253762676723505592) -->
-    <skip />
+    <string name="authentication_required" msgid="8030880723643436099">"এই নিৰ্দেশাৱলী চাবলৈ <xliff:g id="NAME">%1$s</xliff:g>ত ছাইন ইন কৰক"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"সমলবোৰ দেখুওৱাব নোৱাৰি"</string>
+    <string name="sign_in" msgid="6253762676723505592">"ছাইন ইন কৰক"</string>
     <string name="new_archive_file_name" msgid="1604650338077249838">"আৰ্কাইভ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g>ক অভাৰৰাইট কৰিবনে?"</string>
-    <!-- no translation found for continue_in_background (1974214559047793331) -->
-    <skip />
+    <string name="continue_in_background" msgid="1974214559047793331">"নেপথ্যত অব্যাহত ৰাখক"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ফ’নত থকা শেহতীয়া ফাইলবোৰ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ফ’নত থকা ফাইল"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ফ’নত থকা <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>ত থকা ফাইল"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>ৰ ফাইল"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>ৰ ফাইল"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ফ’নত থকা শেহতীয়া চিত্ৰ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ফ’নত থকা চিত্ৰ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>ত থকা চিত্ৰ"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>ৰ চিত্ৰ"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>ৰ পৰা চিত্ৰ"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"প্রতিচ্ছবি"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"অডিঅ’"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ভিডিঅ’"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"দস্তাবেজ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ফ’ল্ডাৰৰ নাম"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"নতুন নাম"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ফাইলটো পূৰ্বদৰ্শন কৰক"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"অন্য এপত ফাইল ব্ৰাউজ কৰক"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"পৰিচয়বিহীন"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\"ত থকা \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" এক্সেছ কৰাৰ অনুমতি দিবনে?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ইয়ে \"<xliff:g id="APPNAME">%1$s</xliff:g>\"ক বৰ্তমান এই অৱস্থানত থকা আৰু ভৱিষ্যতে এই অৱস্থানত জমা কৰা সকলো ফাইল সম্পূৰ্ণভাৱে এক্সেছ কৰাৰ অনুমতি দিব।"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"এই ফ’নটো সন্ধান কৰক"</string>
 </resources>
diff --git a/res/values-az/config.xml b/res/values-az/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-az/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index c9046d7..8e44c59 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Paylaşın"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Sil"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Hamısını seçin"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Seçin"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Çeşidləyin..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Buraya kopyalayın:"</string>
     <string name="menu_move" msgid="2310760789561129882">"Daşıyın..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Sıxışdırın"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Növ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Ölçü"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Dəyişmiş"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Fayl adı (A-dan Z-yə)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Növ (A-dan Z-yə)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Ölçü (əvvəlcə ən kiçik olan)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Dəyişiklik (əvvəlcə ən köhnə olan)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Fayl adı (Z-dən A-ya)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Növ (Z-dən A-ya)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Ölçü (əvvəlcə ən böyük olan)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Dəyişiklik (əvvəlcə ən yeni olan)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sıralama"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> üzrə sıralayın"</string>
     <string name="directory_items" msgid="6645621978998614003">"Elementlərin sayı"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Artan sıra ilə"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Azalan sıra ilə"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini açın"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Kökləri göstərin"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Kökləri gizlədin"</string>
     <string name="save_error" msgid="8631128801982095782">"Sənədi yadda saxlaya bilmədi"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element silinir.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Geri qaytarın"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopyalanmaq üçün hazırlanır..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Sıxılma üçün hazırlanır…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Çıxarmaq üçün hazırlanır…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Köçürmə üçün hazırlanır..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Silmək üçün hazırlanır..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Hazırlanır..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Hazırlanır..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Hazırlanır..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Hazırlanır..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Hazırlanır..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> element kopyalana bilmədi</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> yaddaşında <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> yaddaşında foto və videolar daxil olmaqla datanıza <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təmin edilsin?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Bir daha soruşmayın"</string>
     <string name="allow" msgid="1275746941353040309">"İcazə verin"</string>
     <string name="deny" msgid="5127201668078153379">"Rədd edin"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arxiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> yenidən yazılsın?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Arxa fonda davam edin"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seçildi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seçildi</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Telefonda son fayllar"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Telefondakı fayllar"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Telefondakı <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazındakı fayllar"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> tətbiqindəki fayllar"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> ünvanındakı fayllar"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Telefondakı ən son şəkillər"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Telefondakı şəkillər"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazındakı şəkillər"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> ünvanındakı şəkillər"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g> ünvanındakı şəkillər"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Şəkillər"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videolar"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Sənədlər"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Qovluq adı"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Yeni ad"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> faylını önizləyin"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Faylları digər tətbiqlərdə axtarın"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonim"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" girişinə icazə verin"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" ünvanında \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" girişinə icazə verilsin?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Bu, \"<xliff:g id="APPNAME">%1$s</xliff:g>\" tətbiqinin hazırda bu ünvanda saxlanılmış bütün fayllara və gələcəkdə saxlanılacaq kontentə girişinə icazə verəcək."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Bu telefonu axtarın"</string>
 </resources>
diff --git a/res/values-b+sr+Latn/config.xml b/res/values-b+sr+Latn/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-b+sr+Latn/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 01d74db..6a5b14b 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Deli"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Izbriši"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Izaberi sve"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Izaberi"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortiraj prema..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiraj u…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Premesti u…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Komprimuj"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tip"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veličina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmenjeno"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Naziv datoteke (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tip (od A do Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Veličina (prvo najmanja)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Menjano (prvo najstarije)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Naziv datoteke (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tip (od Z do A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Veličina (prvo najveća)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Menjano (prvo najnovije)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortiranje prema"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sortirano prema: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Broj stavki"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Rastuće"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Opadajuće"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Otvorite aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Prikaži osnovne direktorijume"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Sakrij osnovne direktorijume"</string>
     <string name="save_error" msgid="8631128801982095782">"Čuvanje dokumenta nije uspelo"</string>
@@ -117,11 +130,11 @@
       <item quantity="other">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> stavki.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Opozovi"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Pripremamo kopiranje…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Pripremaju se za komprimovanje…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Izdvajanje se priprema…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Pripremamo premeštanje…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Pripremamo brisanje…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Priprema se..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Priprema se..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Priprema se..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Priprema se..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Priprema se..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> stavke nije uspelo</item>
@@ -188,7 +201,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Želite li da dozvolite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> da pristupa direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na memorijskom prostoru <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Želite li da dozvolite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> da pristupa direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Želite li da dozvolite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> da pristupa podacima, uključujući slike i video, na memorijskom prostoru <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ne pitaj ponovo"</string>
     <string name="allow" msgid="1275746941353040309">"Dozvoli"</string>
     <string name="deny" msgid="5127201668078153379">"Odbij"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -227,4 +239,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhiva<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Želite da zamenite <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Nastavi u pozadini"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Izabrana je <xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+      <item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+      <item quantity="other">Izabrano je <xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nedavne datoteke na telefonu"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Datoteke na telefonu"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> na telefonu"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Datoteke na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Datoteke iz aplikacije <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Datoteke iz aplikacije <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nedavne slike na telefonu"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Slike na telefonu"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Slike na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Slike iz: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Slike iz: <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Slike"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Zvuk"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video snimci"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Naziv direktorijuma"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novi naziv"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Pregledajte datoteku <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Pregledajte datoteke u drugim aplikacijama"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonimna"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Dozvolite pristup direktorijumu „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Želite li da dozvolite pristup direktorijumu „<xliff:g id="DIRECTORY">%1$s</xliff:g>“ na „<xliff:g id="ROOT">%2$s</xliff:g>“?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"To će dozvoliti aplikaciji „<xliff:g id="APPNAME">%1$s</xliff:g>“ da ima potpun pristup svim datotekama koje se trenutno čuvaju na ovoj lokaciji, kao i bilo kom sadržaju koji će se tu čuvati u budućnosti."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Pretražite ovaj telefon"</string>
 </resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index d059b4b..80364c6 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Абагуліць"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Выдаліць"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Выбраць усе"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Выбраць"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Сартаваць па…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Капіраваць у…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Перамясціць у…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Сціснуць"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тып"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Памер"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Зменены"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"назве файла (ад А да Я)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"тыпе (ад А да Я)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"памеры (спачатку меншыя)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"зменах (спачатку старыя)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"назве файла (ад Я да А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"тыпе (ад Я да А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"памеры (спачатку большыя)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"зменах (спачатку новыя)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Сартаваць па"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Адсартавана па <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Колькасць элементаў"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Па ўзрастанні"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Па ўбыванні"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Адкрыць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="drawer_open" msgid="8071673398187261741">"Паказаць каранёвыя папкі"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Схаваць каранёвыя папкі"</string>
     <string name="save_error" msgid="8631128801982095782">"Не атрымалася захаваць дакумент"</string>
@@ -122,11 +135,11 @@
       <item quantity="other">Ідзе выдаленне <xliff:g id="COUNT_1">%1$d</xliff:g> элемента.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Адрабіць"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Ідзе падрыхтоўка да капіравання…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Ідзе падрыхтоўка да сціскання…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Ідзе падрыхтоўка да вымання…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Падрыхтоўваецца перамяшчэнне…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Ідзе падрыхтоўка да выдалення…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Падрыхтоўка…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Падрыхтоўка…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Падрыхтоўка…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Падрыхтоўка…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Падрыхтоўка…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Не атрымалася скапіраваць <xliff:g id="COUNT_1">%1$d</xliff:g> элемент</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да каталога <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> у <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да каталога <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да вашых даных, у тым ліку фатаграфій і відэа, у <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Больш не пытацца"</string>
     <string name="allow" msgid="1275746941353040309">"Дазволіць"</string>
     <string name="deny" msgid="5127201668078153379">"Адмовіць"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"архіў<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Перазапісаць <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Працягнуць у фонавым рэжыме"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Выбрана: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="few">Выбрана: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="many">Выбрана: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Выбрана: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Нядаўнія файлы на тэлефоне"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Файлы на тэлефоне"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> на тэлефоне"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Файлы на прыладзе \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Файлы з: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Файлы з: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Нядаўнія відарысы з тэлефона"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Відарысы на тэлефоне"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Відарысы на прыладзе <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Відарысы са сховішча <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Відарысы са сховішча <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Відарысы"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аўдыя"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Відэа"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Дакументы"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Назва папкі"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Новая назва"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Папярэдні прагляд файла \"<xliff:g id="FILENAME">%1$s</xliff:g>\""</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Пошук файлаў у іншых праграмах"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Ананімная"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Дазволіць доступ да каталога \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Дазволіць доступ да каталога \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" (\"<xliff:g id="ROOT">%2$s</xliff:g>\")?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Гэта дасць праграме \"<xliff:g id="APPNAME">%1$s</xliff:g>\" поўны доступ да ўсіх файлаў, якія захоўваюцца зараз або будуць захаваны ў гэтым месцы."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Пошук на гэтым тэлефоне"</string>
 </resources>
diff --git a/res/values-bg/config.xml b/res/values-bg/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-bg/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 14bc483..4260552 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Споделяне"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Изтриване"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Избиране на всичко"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Избиране"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Сортиране по..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Копиране във…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Преместване във…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Компресиране"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Размер"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Променено"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"име на файла (А – Я)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"тип (А – Я)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"размер (първо най-малките)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"промяна (първо най-старите)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"име на файла (Я – А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"тип (Я – А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"размер (първо най-големите)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"промяна (първо най-новите)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Сортиране по"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Сортирани по <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Брой елементи"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Възходящ ред"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Низходящ ред"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Отваряне на <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Показване на основните елементи"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Скриване на основните елементи"</string>
     <string name="save_error" msgid="8631128801982095782">"Запазването на документа не бе успешно"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> елемент се изтрива.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Отмяна"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Подготвя се за копиране…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Подготвя се за компресиране…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Извличането се подготвя…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Преместването се подготвя…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Подготвя се за изтриване..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Подготвя се..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Подготвя се..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Подготвя се..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Подготвя се..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Подготвя се..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> елемента не можаха да бъдат копирани</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ в/ъв <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до данните ви в хранилището (<xliff:g id="STORAGE"><i>^2</i></xliff:g>), включително снимки и видеоклипове?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Без повторно питане"</string>
     <string name="allow" msgid="1275746941353040309">"Разрешаване"</string>
     <string name="deny" msgid="5127201668078153379">"Отказ"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"<xliff:g id="EXTENSION">%s</xliff:g> архивен файл"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Да се презапише ли <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Продължаване на заден план"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">Избрахте <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Избрахте <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Скорошни файлове на телефона"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Файлове на телефона"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> на телефона"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Файлове от <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Файлове от <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Файлове от <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Скорошни изображения в телефона"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Изображения в телефона"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Изображения в устройството <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Изображения от <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Изображения от <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Изображения"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аудио"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Видеоклипове"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документи"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Име на папката"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Ново име"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Визуализация на файла <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Преглед на файлове в други приложения"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Анонимно"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Разрешаване на достъп до „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Да се разреши ли достъп до „<xliff:g id="DIRECTORY">%1$s</xliff:g>“ на „<xliff:g id="ROOT">%2$s</xliff:g>“?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Така „<xliff:g id="APPNAME">%1$s</xliff:g>“ ще получи пълен достъп до всички файлове, които понастоящем се съхраняват в това местоположение, както и до всяко съдържание, което ще се съхранява тук в бъдеще."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Търсете в този телефон"</string>
 </resources>
diff --git a/res/values-bn/config.xml b/res/values-bn/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-bn/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index a804b73..0fef2a8 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"শেয়ার করুন"</string>
     <string name="menu_delete" msgid="1022254131543256626">"মুছুন"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"সবগুলি বেছে নিন"</string>
+    <string name="menu_select" msgid="1366061076507142387">"বেছে নিন"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"এই অনুসারে সাজান..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"এতে কপি করুন…"</string>
     <string name="menu_move" msgid="2310760789561129882">"এতে সরান…"</string>
     <string name="menu_compress" msgid="37539111904724188">"সঙ্কুচিত করুন"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ধরণ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"আকার"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"শেষ সংশোধিত"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ফাইলের নাম (A থেকে Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ধরন (A থেকে Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"সাইজ (সবচেয়ে ছোট আগে)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"পরিবর্তন করা হয়েছে (পুরনোগুলি প্রথমে)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ফাইলের নাম (Z থেকে A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ধরন (Z থেকে A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"সাইজ (সবচেয়ে বড় আগে)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"পরিবর্তন করা হয়েছে (নতুনগুলি প্রথমে)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"এই অনুসারে সাজান"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> অনুযায়ী সাজানো"</string>
     <string name="directory_items" msgid="6645621978998614003">"আইটেমের সংখ্যা"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ঊর্ধ্বক্রম"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"নিম্নক্রম"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> খুলুন"</string>
     <string name="drawer_open" msgid="8071673398187261741">"রুটগুলি দেখান"</string>
     <string name="drawer_close" msgid="4263880768630848848">"রুটগুলি লুকান"</string>
     <string name="save_error" msgid="8631128801982095782">"দস্তাবেজ সংরক্ষণ করা গেল না"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম মুছে দেওয়া হচ্ছে।</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"পূর্বাবস্থায় ফিরুন"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"কপি করার জন্য প্রস্তুত হচ্ছে…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"সঙ্কুচিত করার জন্য প্রস্তুত করা হচ্ছে…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"বের করার জন্য প্রস্তুতি চলছে…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"সরানোর জন্য প্রস্তুত হচ্ছে…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"মোছার জন্য প্রস্তুত হচ্ছে…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"প্রস্তুত হচ্ছে…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"প্রস্তুত হচ্ছে…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"প্রস্তুত হচ্ছে…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"প্রস্তুত হচ্ছে…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"প্রস্তুত হচ্ছে…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম কপি করা হয়নি</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="STORAGE"><i>^3</i></xliff:g> এ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার অনুমতি দেবেন?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার অনুমতি দেবেন?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> এ থাকা ফটো ও ভিডিওগুলি সমেত <xliff:g id="APPNAME"><b>^1</b></xliff:g> কে আপনার ডেটা অ্যাক্সেস করার অনুমতি দেবেন?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"আবার জিজ্ঞাসা করবেন না"</string>
     <string name="allow" msgid="1275746941353040309">"অনুমতি দিন"</string>
     <string name="deny" msgid="5127201668078153379">"প্রত্যাখ্যান করুন"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"সংরক্ষণ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ওভাররাইট করবেন?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"পটভূমিতে চালিয়ে যান"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি বেছে নেওয়া হয়েছে</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি বেছে নেওয়া হয়েছে</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ফোনে আসা নতুন ফাইল"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ফোনে সেভ করা ফাইলগুলি"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ফোনে সেভ করা <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> ডিভাইসে সেভ করা ফাইলগুলি"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>-এ সেভ করা ফাইলগুলি"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>-এ সেভ করা ফাইলগুলি"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ফোনে সম্প্রতি আসা ছবি"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ফোনের ছবি"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>-এর ছবি"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>-এর ছবি"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>-এর ছবি"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ছবি"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"অডিও"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ভিডিও"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ডকুমেন্ট"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ফোল্ডারের নাম"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"নতুন নাম"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ফাইলের প্রিভিউ দেখুন"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"অন্যান্য অ্যাপে ফাইল ব্রাউজ করুন"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"বেনামী"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"-এ অ্যাক্সেসের অনুমতি দিন"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\"-এর <xliff:g id="DIRECTORY">%1$s</xliff:g>-এ অ্যাক্সেস করার অনুমতি দিতে চান?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"এই লোকেশনে বর্তমানে থাকা এবং ভবিষ্যতে রাখা যেকোনও ফাইলে <xliff:g id="APPNAME">%1$s</xliff:g> এর অ্যাক্সেস করার অনুমতি দেয়।"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"এই ফোনটি খুঁজুন"</string>
 </resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index e15712c..fc1b68c 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Dijeli"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Izbriši"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Odaberi sve"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Odaberi"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Poredaj po…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiraj u…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Premjesti u…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Kompresiraj"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Vrsta"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veličina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmijenjeno"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Naziv fajla (A – Ž)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Vrsta (A – Ž)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Veličina (prvo najmanje)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Izmijenjeno (prvo najstariji)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Naziv fajla (Ž – A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Vrsta (Ž – A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Veličina (prvo najveće)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Izmijenjeno (prvo najnoviji)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Poredaj po"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Poredano po: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Broj stavki"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Rastuće"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Opadajuće"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Otvorite aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Prikaži korijenske fordere"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Sakrij korijenske foldere"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokument nije pohranjen"</string>
@@ -84,7 +97,7 @@
     <string name="toast_no_application" msgid="7555319548595113121">"Nije moguće otvoriti fajl"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Nije moguće otvoriti fajlove u arhivama"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"Nije moguće izbrisati neke dokumente"</string>
-    <string name="share_via" msgid="8725082736005677161">"Dijeli koristeći aplikaciju"</string>
+    <string name="share_via" msgid="8725082736005677161">"Dijeli pomoću aplikacije"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"Kopiraju se fajlovi"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"Kompresovanje fajlova"</string>
     <string name="extract_notification_title" msgid="5067393961754430469">"Izdvajanje fajlova"</string>
@@ -117,11 +130,11 @@
       <item quantity="other">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> stavki.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Opozovi radnju"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Priprema za kopiranje…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Priprema za kompresiranje…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Priprema za izdvajanje…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Priprema za premještanje…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Priprema za brisanje…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Pripremanje…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Pripremanje…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Pripremanje…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Pripremanje…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Pripremanje…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> stavke nije uspjelo</item>
@@ -188,7 +201,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na pohrani <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup svojim podacima, uključujući fotografije i videozapise, na pohrani: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ne pitaj ponovo"</string>
     <string name="allow" msgid="1275746941353040309">"Dozvoli"</string>
     <string name="deny" msgid="5127201668078153379">"Odbij"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -227,4 +239,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhiva<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Želite li prepisati fajl <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Nastavi u pozadini"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka je odabrana</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nedavni fajlovi na telefonu"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fajlovi na telefonu"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> na telefonu"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fajlovi na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fajlovi usluge <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fajlovi usluge <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nedavne slike na telefonu"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Slike na telefonu"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Slike na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Slike s usluge <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Slike s usluge <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Slike"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Zvuk"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videozapisi"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Ime foldera"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novo ime"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Pregled fajla <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Pretraživanje fajlova u drugim aplikacijama"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonimno"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Dozvoli pristup direktoriju \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Omogućiti pristup direktoriju \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" na uređaju \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Aplikaciji \"<xliff:g id="APPNAME">%1$s</xliff:g>\" će biti dozvoljen potpuni pristup svim fajlovima koji su trenutno pohranjeni na ovoj lokaciji te bilo kojem sadržaju koji se ubuduće pohrani ovdje."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Pretražite ovaj telefon"</string>
 </resources>
diff --git a/res/values-ca/config.xml b/res/values-ca/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ca/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 97789d7..ff413b3 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Comparteix"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Suprimeix"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Selecciona-ho tot"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Selecciona"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordena per..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copia a…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Mou a…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimeix"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipus"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Mida"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificat"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nom del fitxer (A-Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipus (A-Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Mida (més petit primer)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Data d\'edició (antics)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nom del fitxer (Z-A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipus (Z-A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Mida (més gros primer)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Data d\'edició (recents)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordena per:"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Ordenat per: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Nombre d\'elements"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendent"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendent"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Obre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostra les arrels"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Amaga les arrels"</string>
     <string name="save_error" msgid="8631128801982095782">"No s\'ha pogut desar el document"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">S\'està suprimint <xliff:g id="COUNT_0">%1$d</xliff:g> element.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Desfés"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"S\'està preparant per copiar…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"S\'està preparant la compressió…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparant per a l\'extracció…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"S\'està preparant per moure\'ls…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"S\'està preparant per suprimir…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"S\'està preparant..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"S\'està preparant..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"S\'està preparant..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"S\'està preparant..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"S\'està preparant..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">No s\'han pogut copiar <xliff:g id="COUNT_1">%1$d</xliff:g> elements</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés a les dades de <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incloses les fotos i els vídeos?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"No m\'ho demanis més"</string>
     <string name="allow" msgid="1275746941353040309">"Permet"</string>
     <string name="deny" msgid="5127201668078153379">"Denega"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"fitxer<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Vols sobreescriure <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continua en segon pla"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elements seleccionats</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element seleccionat</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Fitxers recents del telèfon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fitxers al telèfon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> al telèfon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fitxers a <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fitxers de: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fitxers de: <xliff:g id="LABEL">%1$s</xliff:g> (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imatges recents del telèfon"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imatges del telèfon"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imatges del dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imatges de: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imatges de: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imatges"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Àudio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nom de la carpeta"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nom nou"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Previsualitza el fitxer <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Cerca fitxers en altres aplicacions"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anònima"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permet l\'accés a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Permetrà que <xliff:g id="APPNAME">%1$s</xliff:g> accedeixi a tots els fitxers que hi ha emmagatzemats actualment en aquesta ubicació i a qualsevol contingut que s\'hi emmagatzemi posteriorment."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Cerca en aquest telèfon"</string>
 </resources>
diff --git a/res/values-cs/config.xml b/res/values-cs/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-cs/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index f768b2d..9c5e027 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Sdílet"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Smazat"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Vybrat vše"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Vybrat"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Řadit podle…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopírovat do…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Přesunout do…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Zkomprimovat"</string>
@@ -65,14 +67,25 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Typ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Velikost"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Změněno"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Název souboru (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Typ (A–Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Velikost (od nejmenšího)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Úprava (od nejstaršího)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Název souboru (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Typ (Z–A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Velikost (od největšího)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Úprava (od nejnovějšího)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Řadit podle"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Seřazeno podle: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Počet položek"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Vzestupně"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Sestupně"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Otevřít aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Zobrazit kořeny"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Skrýt kořeny"</string>
     <string name="save_error" msgid="8631128801982095782">"Uložení dokumentu se nezdařilo"</string>
     <string name="create_error" msgid="3092144450044861994">"Složku se nepodařilo vytvořit"</string>
-    <string name="query_error" msgid="6625421453613879336">"Obsah nyní nelze načíst"</string>
+    <string name="query_error" msgid="6625421453613879336">"Obsah teď nelze načíst"</string>
     <string name="root_recent" msgid="1080156975424341623">"Nedávné"</string>
     <string name="root_available_bytes" msgid="8269870862691408864">"Volný prostor: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="6521366147466512289">"Služby úložiště"</string>
@@ -122,11 +135,11 @@
       <item quantity="one">Mazání <xliff:g id="COUNT_0">%1$d</xliff:g> položky</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Vrátit zpět"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Příprava na kopírování…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Příprava na komprimaci…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Příprava na rozbalení…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Příprava na přesunutí…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Příprava na mazání…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Příprava..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Příprava..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Příprava..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Příprava..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Příprava..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="few"> <xliff:g id="COUNT_1">%1$d</xliff:g> položky nebylo možné zkopírovat</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložišti <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup ke svým datům v úložišti <xliff:g id="STORAGE"><i>^2</i></xliff:g>, včetně fotek a videí?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Příště se neptat"</string>
     <string name="allow" msgid="1275746941353040309">"Povolit"</string>
     <string name="deny" msgid="5127201668078153379">"Odmítnout"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Přepsat soubor <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Pokračovat na pozadí"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="few">Vybrány <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+      <item quantity="many">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+      <item quantity="other">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položek</item>
+      <item quantity="one">Vybrána <xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nejnovější soubory v telefonu"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Soubory v telefonu"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> v telefonu"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Soubory v zařízení <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Soubory ze služby <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Soubory ze služby <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nejnovější obrázky v telefonu"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Obrázky v telefonu"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Obrázky v zařízení <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Obrázky ze zařízení <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Obrázky ze zařízení <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Obrázky"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Zvuk"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videa"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenty"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Název složky"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nový název"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Zobrazit náhled souboru <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Procházet soubory v ostatních aplikacích"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymní"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Povolit přístup k adresáři „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Povolit přístup k adresáři <xliff:g id="DIRECTORY">%1$s</xliff:g> na zařízení <xliff:g id="ROOT">%2$s</xliff:g>?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> získá úplný přístup ke všem souborů, které jsou aktuálně uložené v tomto umístění, a k veškerému obsahu, který zde bude uložen v budoucnu."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Hledat v telefonu"</string>
 </resources>
diff --git a/res/values-da/config.xml b/res/values-da/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-da/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 20da773..716c7e7 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Del"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Slet"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Vælg alle"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Vælg"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortér efter…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiér til…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Flyt til…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Komprimer"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Størrelse"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ændret"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Filnavn (A til Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A til Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Størrelse (mindste først)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Ændret (ældste først)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Filnavn (Z til A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z til A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Størrelse (største først)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Ændret (nyeste først)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortér efter"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sorteret efter <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Antal elementer"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stigende rækkefølge"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Faldende rækkefølge"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Åbn <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Vis rødder"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Skjul rødder"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokumentet kunne ikke gemmes"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Sletter <xliff:g id="COUNT_1">%1$d</xliff:g> elementer.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Fortryd"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Forbereder kopiering…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Gør klar til komprimering…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Forbereder udpakningen…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Forbereder flytning…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Forbereder til sletning…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Forbereder…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Forbereder…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Forbereder…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Forbereder…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Forbereder…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> af <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element kunne ikke kopieres</item>
@@ -134,7 +147,7 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element kunne ikke slettes</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementer kunne ikke slettes</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="2385563502445129570">"Tryk for at se oplysninger"</string>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"Tryk for at se info"</string>
     <string name="close" msgid="905969391788869975">"Luk"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
       <item quantity="one">Følgende fil blev ikke kopieret: <xliff:g id="LIST_1">%1$s</xliff:g></item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til indekset <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til indekset <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til dine data, herunder billeder og videoer på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Spørg ikke igen"</string>
     <string name="allow" msgid="1275746941353040309">"Tillad"</string>
     <string name="deny" msgid="5127201668078153379">"Afvis"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arkiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Vil du overskrive <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Fortsæt i baggrunden"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Seneste filer på telefonen"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Filer på telefonen"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> på telefonen"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Filer på <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Filer fra <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Filer fra <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Seneste billeder på telefonen"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Billeder på telefonen"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Billeder på <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Billeder fra <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Billeder fra <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Billeder"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Lyd"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videoer"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenter"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Mappenavn"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nyt navn"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Se forhåndsvisning af filen <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Gennemse filer i andre apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonym"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Tillad adgang til \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Vil du tillade adgang til \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" i \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Dette åbner \"<xliff:g id="APPNAME">%1$s</xliff:g>\", så den har fuld adgang til alle filer, der i øjeblikket er gemt på denne placering, og eventuelt fremtidigt indhold, som er gemt her."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Søg på denne telefon"</string>
 </resources>
diff --git a/res/values-de/config.xml b/res/values-de/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-de/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 703b791..92ca886 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Teilen"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Löschen"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Alle auswählen"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Auswählen"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortieren nach…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopieren nach…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Verschieben nach…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Komprimieren"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Dateityp"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Größe"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Geändert"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Dateiname (A bis Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Typ (A bis Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Größe (kleinste zuerst)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Geändert (älteste zuerst)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Dateiname (Z bis A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Typ (Z bis A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Größe (größte zuerst)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Geändert (neueste zuerst)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortieren nach"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Nach <xliff:g id="LABEL">%s</xliff:g> sortiert"</string>
     <string name="directory_items" msgid="6645621978998614003">"Anzahl der Elemente"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Aufsteigend"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Absteigend"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> öffnen"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Root-Verzeichnis anzeigen"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Root-Verzeichnis ausblenden"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokument konnte nicht gespeichert werden"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Element wird gelöscht.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Rückgängig"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopieren wird vorbereitet…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Vorbereitung für Komprimierung…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Dekomprimierung wird vorbereitet"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Verschieben wird vorbereitet…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Löschen wird vorbereitet…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Wird vorbereitet…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Wird vorbereitet…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Wird vorbereitet…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Wird vorbereitet…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Wird vorbereitet…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Elemente konnten nicht kopiert werden</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> auf <xliff:g id="STORAGE"><i>^3</i></xliff:g> geben?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> geben?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf die Daten auf <xliff:g id="STORAGE"><i>^2</i></xliff:g> geben, einschließlich Fotos und Videos?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Nicht mehr fragen"</string>
     <string name="allow" msgid="1275746941353040309">"Zulassen"</string>
     <string name="deny" msgid="5127201668078153379">"Ablehnen"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> überschreiben?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Im Hintergrund fortsetzen"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ausgewählt</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ausgewählt</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Kürzlich verwendete Dateien auf dem Smartphone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Dateien auf dem Smartphone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> auf dem Smartphone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Dateien auf <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Dateien von <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Dateien von <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Neue Bilder auf dem Smartphone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Bilder auf dem Smartphone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Bilder auf <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Bilder aus <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Bilder aus <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Bilder"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumente"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Ordnername"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Neuer Name"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Datei \"<xliff:g id="FILENAME">%1$s</xliff:g>\" als Vorschau ansehen"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Dateien in anderen Apps ansehen"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonym"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Zugriff auf \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" erlauben"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"<xliff:g id="APPNAME">%1$s</xliff:g> hat dann uneingeschränkten Zugriff auf alle Dateien, die aktuell an diesem Ort gespeichert sind, sowie auf sämtliche Inhalte, die zukünftig dort gespeichert werden."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Auf diesem Smartphone suchen"</string>
 </resources>
diff --git a/res/values-el/config.xml b/res/values-el/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-el/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 003ef4c..731e64d 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Κοινοποίηση"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Διαγραφή"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Επιλογή όλων"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Επιλογή"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ταξινόμηση κατά…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Αντιγραφή σε…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Μετακίνηση σε…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Συμπίεση"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Τύπος"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Μέγεθος"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Τροποποιημένα"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Όνομα αρχείου (Α προς Ω)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Τύπος (A προς Ω)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Μέγεθος (από μικρότερο)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Τροποπ. (από παλαιότερο)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Όνομα αρχείου (Ω προς A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Τύπος (Ω προς A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Μέγεθος (από μεγαλύτερο)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Τροποπ. (από νεότερο)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ταξινόμηση κατά"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Ταξινόμηση κατά <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Αριθμός στοιχείων"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Αύξουσα"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Φθίνουσα"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Ανοίξτε την εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Εμφάνιση ριζών"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Απόκρυψη ριζών"</string>
     <string name="save_error" msgid="8631128801982095782">"Αποτυχία αποθήκευσης εγγράφου"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Διαγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> στοιχείου.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Αναίρεση"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Προετοιμασία για αντιγραφή…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Προετοιμασία για συμπίεση…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Προετοιμασία για εξαγωγή…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Προετοιμασία για μετακίνηση…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Προετοιμασία για διαγραφή…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Προετοιμασία…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Προετοιμασία…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Προετοιμασία…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Προετοιμασία…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Προετοιμασία…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> στοιχείων</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^3</i></xliff:g>;"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>;"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στα δεδομένα σας, συμπεριλαμβανομένων των φωτογραφιών και των βίντεο, στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^2</i></xliff:g>;"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Να μην ερωτηθώ ξανά"</string>
     <string name="allow" msgid="1275746941353040309">"Αποδοχή"</string>
     <string name="deny" msgid="5127201668078153379">"Απόρριψη"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"αρχειοθέτηση<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Αντικατάσταση <xliff:g id="NAME">%1$s</xliff:g>;"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Συνέχεια στο παρασκήνιο"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> επιλεγμένα</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> επιλεγμένο</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Πρόσφατα αρχεία στο τηλέφωνο"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Αρχεία στο τηλέφωνο"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> στο τηλέφωνο"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Αρχεία στη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Αρχεία από <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Αρχεία από <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Πρόσφατες εικόνες στο τηλέφωνο"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Εικόνες στο τηλέφωνο"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Εικόνες στη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Εικόνες από <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Εικόνες από <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Εικόνες"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Ήχος"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Βίντεο"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Έγγραφα"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Όνομα φακέλου"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Νέο όνομα"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Προεπισκόπηση του αρχείου <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Αναζήτηση αρχείων σε άλλες εφαρμογές"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Ανώνυμη"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Να επιτρέπεται η πρόσβαση σε \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Να επιτρέπεται η πρόσβαση σε \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" στο \"<xliff:g id="ROOT">%2$s</xliff:g>\";"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Θα επιτρέπεται στην εφαρμογή \"<xliff:g id="APPNAME">%1$s</xliff:g>\" να έχει πλήρη πρόσβαση σε όλα τα αρχεία που είναι αποθηκευμένα αυτήν τη στιγμή σε αυτήν την τοποθεσία και τυχόν περιεχόμενο που θα αποθηκευτεί μελλοντικά εδώ."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Αναζήτηση αυτού του τηλεφώνου"</string>
 </resources>
diff --git a/res/values-en-rAU/config.xml b/res/values-en-rAU/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-en-rAU/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 8ffcdbc..3ccf3eb 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Shared"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Delete"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Select all"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Select"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sort by..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copy to…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Move to…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"File name (A to Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A to Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Size (smallest first)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modified (oldest first)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"File name (Z to A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z to A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Size (largest first)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modified (newest first)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sort by"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sorted by <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Hide roots"</string>
     <string name="save_error" msgid="8631128801982095782">"Failed to save document"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Undo"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparing for copy…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparing for compress…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparing for extract…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparing for move…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparing to delete…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparing..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparing..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparing..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparing..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparing..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Don\'t ask again"</string>
     <string name="allow" msgid="1275746941353040309">"Allow"</string>
     <string name="deny" msgid="5127201668078153379">"Deny"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Overwrite <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continue in background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Recent files on phone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Files on phone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> on phone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Files on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Files from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Files from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Recent images on phone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Images on phone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Images on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Images from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Images from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Images"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Folder name"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"New name"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Preview the file <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Browse files in other apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymous"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\'"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\' on \'<xliff:g id="ROOT">%2$s</xliff:g>\'?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"It will allow \'<xliff:g id="APPNAME">%1$s</xliff:g>\' to have full access to all files currently stored under this location, and any future content stored here."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Search this phone"</string>
 </resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 8ffcdbc..3ccf3eb 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Shared"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Delete"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Select all"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Select"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sort by..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copy to…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Move to…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"File name (A to Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A to Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Size (smallest first)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modified (oldest first)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"File name (Z to A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z to A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Size (largest first)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modified (newest first)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sort by"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sorted by <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Hide roots"</string>
     <string name="save_error" msgid="8631128801982095782">"Failed to save document"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Undo"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparing for copy…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparing for compress…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparing for extract…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparing for move…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparing to delete…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparing..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparing..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparing..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparing..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparing..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Don\'t ask again"</string>
     <string name="allow" msgid="1275746941353040309">"Allow"</string>
     <string name="deny" msgid="5127201668078153379">"Deny"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Overwrite <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continue in background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Recent files on phone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Files on phone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> on phone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Files on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Files from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Files from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Recent images on phone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Images on phone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Images on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Images from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Images from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Images"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Folder name"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"New name"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Preview the file <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Browse files in other apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymous"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\'"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\' on \'<xliff:g id="ROOT">%2$s</xliff:g>\'?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"It will allow \'<xliff:g id="APPNAME">%1$s</xliff:g>\' to have full access to all files currently stored under this location, and any future content stored here."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Search this phone"</string>
 </resources>
diff --git a/res/values-en-rGB/config.xml b/res/values-en-rGB/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-en-rGB/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 8ffcdbc..3ccf3eb 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Shared"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Delete"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Select all"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Select"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sort by..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copy to…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Move to…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"File name (A to Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A to Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Size (smallest first)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modified (oldest first)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"File name (Z to A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z to A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Size (largest first)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modified (newest first)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sort by"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sorted by <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Hide roots"</string>
     <string name="save_error" msgid="8631128801982095782">"Failed to save document"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Undo"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparing for copy…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparing for compress…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparing for extract…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparing for move…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparing to delete…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparing..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparing..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparing..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparing..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparing..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Don\'t ask again"</string>
     <string name="allow" msgid="1275746941353040309">"Allow"</string>
     <string name="deny" msgid="5127201668078153379">"Deny"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Overwrite <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continue in background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Recent files on phone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Files on phone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> on phone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Files on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Files from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Files from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Recent images on phone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Images on phone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Images on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Images from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Images from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Images"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Folder name"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"New name"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Preview the file <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Browse files in other apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymous"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\'"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\' on \'<xliff:g id="ROOT">%2$s</xliff:g>\'?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"It will allow \'<xliff:g id="APPNAME">%1$s</xliff:g>\' to have full access to all files currently stored under this location, and any future content stored here."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Search this phone"</string>
 </resources>
diff --git a/res/values-en-rIN/config.xml b/res/values-en-rIN/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-en-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 8ffcdbc..3ccf3eb 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Shared"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Delete"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Select all"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Select"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sort by..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copy to…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Move to…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compress"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type:"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Size"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modified"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"File name (A to Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A to Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Size (smallest first)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modified (oldest first)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"File name (Z to A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z to A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Size (largest first)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modified (newest first)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sort by"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sorted by <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Number of items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascending"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descending"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Show roots"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Hide roots"</string>
     <string name="save_error" msgid="8631128801982095782">"Failed to save document"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Undo"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparing for copy…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparing for compress…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparing for extract…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparing for move…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparing to delete…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparing..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparing..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparing..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparing..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparing..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Don\'t ask again"</string>
     <string name="allow" msgid="1275746941353040309">"Allow"</string>
     <string name="deny" msgid="5127201668078153379">"Deny"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Overwrite <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continue in background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Recent files on phone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Files on phone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> on phone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Files on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Files from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Files from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Recent images on phone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Images on phone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Images on <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Images from <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Images from <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Images"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Folder name"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"New name"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Preview the file <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Browse files in other apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymous"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\'"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Allow access to \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\' on \'<xliff:g id="ROOT">%2$s</xliff:g>\'?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"It will allow \'<xliff:g id="APPNAME">%1$s</xliff:g>\' to have full access to all files currently stored under this location, and any future content stored here."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Search this phone"</string>
 </resources>
diff --git a/res/values-en-rXC/inspector_strings.xml b/res/values-en-rXC/inspector_strings.xml
index ace8d48..9a1fe47 100644
--- a/res/values-en-rXC/inspector_strings.xml
+++ b/res/values-en-rXC/inspector_strings.xml
@@ -16,34 +16,34 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="inspector_title" msgid="1924760928091740238">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎Info‎‏‎‎‏‎"</string>
-    <string name="inspector_load_error" msgid="7522190243413249291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎File info could not be loaded‎‏‎‎‏‎"</string>
-    <string name="inspector_debug_section" msgid="2576052661505700421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎Debug info (dev only)‎‏‎‎‏‎"</string>
-    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎Raw metadata: ‎‏‎‎‏‏‎<xliff:g id="METADATATYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="inspector_metadata_section" msgid="6077622515328240575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎Media details‎‏‎‎‏‎"</string>
-    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎This kind of file opens with‎‏‎‎‏‎"</string>
-    <string name="handler_app_belongs_to" msgid="5444507329303253553">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎This file is supplied by‎‏‎‎‏‎"</string>
-    <string name="handler_app_not_selected" msgid="1294439257183908786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎Not selected‎‏‎‎‏‎"</string>
-    <string name="handler_app_unknown" msgid="5911661530593229287">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎Unknown‎‏‎‎‏‎"</string>
-    <string name="metadata_dimensions" msgid="6112907724016659801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎Dimensions‎‏‎‎‏‎"</string>
-    <string name="metadata_dimensions_format" msgid="6138765871412005962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="WIDTH">%1$d</xliff:g>‎‏‎‎‏‏‏‎ x ‎‏‎‎‏‏‎<xliff:g id="HEIGHT">%2$d</xliff:g>‎‏‎‎‏‏‏‎ - ‎‏‎‎‏‏‎<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>‎‏‎‎‏‏‏‎MP‎‏‎‎‏‎"</string>
-    <string name="metadata_coordinates" msgid="6897383227370702734">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎Coordinates‎‏‎‎‏‎"</string>
-    <string name="metadata_coordinates_format" msgid="1402724596764547761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="LATITUDE">%1$,.3f</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="LONGITUDE">%2$,.3f</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="metadata_altitude" msgid="8063792127436794294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎Altitude‎‏‎‎‏‎"</string>
-    <string name="metadata_camera" msgid="2363009732801281319">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎Camera‎‏‎‎‏‎"</string>
-    <string name="metadata_camera_format" msgid="1494489751904311612">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="MAKE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎<xliff:g id="MODEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="metadata_aperture" msgid="6538741952698935357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎Aperture‎‏‎‎‏‎"</string>
-    <string name="metadata_shutter_speed" msgid="8204739885103326131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎Shutter speed‎‏‎‎‏‎"</string>
-    <string name="metadata_duration" msgid="3115494422055472715">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎Duration‎‏‎‎‏‎"</string>
-    <string name="metadata_date_time" msgid="1090351199248114406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎Taken on‎‏‎‎‏‎"</string>
-    <string name="metadata_focal_length" msgid="3440735161407699893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎Focal length‎‏‎‎‏‎"</string>
-    <string name="metadata_focal_format" msgid="8542211707962355623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="LENGTH">%1$.2f </xliff:g>‎‏‎‎‏‏‏‎mm‎‏‎‎‏‎"</string>
-    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎ISO equivalent‎‏‎‎‏‎"</string>
-    <string name="metadata_iso_format" msgid="4153285204012694861">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎ISO ‎‏‎‎‏‏‎<xliff:g id="ISO_SPEED">%1$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="metadata_artist" msgid="8972421485694988540">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎Artist‎‏‎‎‏‎"</string>
-    <string name="metadata_composer" msgid="4696926808308256056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎Composer‎‏‎‎‏‎"</string>
-    <string name="metadata_album" msgid="1661699531214720236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎Album‎‏‎‎‏‎"</string>
-    <string name="metadata_address" msgid="1849921023707744640">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎Location‎‏‎‎‏‎"</string>
-    <string name="debug_stream_types" msgid="2088565280360139333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎Stream types‎‏‎‎‏‎"</string>
-    <string name="debug_raw_size" msgid="7487139640175650185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎Raw size (bytes)‎‏‎‎‏‎"</string>
+    <string name="inspector_title" msgid="1924760928091740238">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎Info‎‏‎‎‏‎"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎File info could not be loaded‎‏‎‎‏‎"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎Debug info (dev only)‎‏‎‎‏‎"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎Raw metadata: ‎‏‎‎‏‏‎<xliff:g id="METADATATYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎Media details‎‏‎‎‏‎"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎This kind of file opens with‎‏‎‎‏‎"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎This file is supplied by‎‏‎‎‏‎"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎Not selected‎‏‎‎‏‎"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎Unknown‎‏‎‎‏‎"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎Dimensions‎‏‎‎‏‎"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="WIDTH">%1$d</xliff:g>‎‏‎‎‏‏‏‎ x ‎‏‎‎‏‏‎<xliff:g id="HEIGHT">%2$d</xliff:g>‎‏‎‎‏‏‏‎ - ‎‏‎‎‏‏‎<xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>‎‏‎‎‏‏‏‎MP‎‏‎‎‏‎"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎Coordinates‎‏‎‎‏‎"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="LATITUDE">%1$,.3f</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="LONGITUDE">%2$,.3f</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎Altitude‎‏‎‎‏‎"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎Camera‎‏‎‎‏‎"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="MAKE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎<xliff:g id="MODEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎Aperture‎‏‎‎‏‎"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎Shutter speed‎‏‎‎‏‎"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎Duration‎‏‎‎‏‎"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎Taken on‎‏‎‎‏‎"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎Focal length‎‏‎‎‏‎"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="LENGTH">%1$.2f </xliff:g>‎‏‎‎‏‏‏‎mm‎‏‎‎‏‎"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎ISO equivalent‎‏‎‎‏‎"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎ISO ‎‏‎‎‏‏‎<xliff:g id="ISO_SPEED">%1$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎Artist‎‏‎‎‏‎"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎Composer‎‏‎‎‏‎"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎Album‎‏‎‎‏‎"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎Location‎‏‎‎‏‎"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎Stream types‎‏‎‎‏‎"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎Raw size (bytes)‎‏‎‎‏‎"</string>
 </resources>
diff --git a/res/values-en-rXC/mimes.xml b/res/values-en-rXC/mimes.xml
index 43489a9..f0ae28a 100644
--- a/res/values-en-rXC/mimes.xml
+++ b/res/values-en-rXC/mimes.xml
@@ -17,29 +17,29 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="generic_extention_file_type" msgid="5947398320635880291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="EXTENSION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ file‎‏‎‎‏‎"</string>
-    <string name="generic_file_type" msgid="1415477154743494280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎File‎‏‎‎‏‎"</string>
-    <string name="image_file_type" msgid="3011633523704887793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎Image‎‏‎‎‏‎"</string>
-    <string name="image_extension_file_type" msgid="992617216367594851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ image‎‏‎‎‏‎"</string>
-    <string name="audio_file_type" msgid="3790525543519624632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎Audio‎‏‎‎‏‎"</string>
-    <string name="audio_extension_file_type" msgid="6334293531796491314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ audio‎‏‎‎‏‎"</string>
-    <string name="video_file_type" msgid="7290473366042482095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎Video‎‏‎‎‏‎"</string>
-    <string name="video_extension_file_type" msgid="6352763029831291433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ video‎‏‎‎‏‎"</string>
-    <string name="archive_file_type" msgid="1463432996680398798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ archive‎‏‎‎‏‎"</string>
-    <string name="apk_file_type" msgid="6004275470389462277">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎Android application‎‏‎‎‏‎"</string>
-    <string name="txt_file_type" msgid="4677767777860724696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎Plain text‎‏‎‎‏‎"</string>
-    <string name="html_file_type" msgid="2034229603117527970">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎HTML document‎‏‎‎‏‎"</string>
-    <string name="pdf_file_type" msgid="3382260303795039988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎PDF document‎‏‎‎‏‎"</string>
-    <string name="word_file_type" msgid="2366349268129894972">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎Word document‎‏‎‎‏‎"</string>
-    <string name="ppt_file_type" msgid="2570841599899893925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎PowerPoint presentation‎‏‎‎‏‎"</string>
-    <string name="excel_file_type" msgid="8363932635044575463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎Excel spreadsheet‎‏‎‎‏‎"</string>
-    <string name="gdoc_file_type" msgid="242328101061228382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎Google document‎‏‎‎‏‎"</string>
-    <string name="gsheet_file_type" msgid="8055591929133067952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎Google spreadsheet‎‏‎‎‏‎"</string>
-    <string name="gslides_file_type" msgid="8359750985956690177">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎Google presentation‎‏‎‎‏‎"</string>
-    <string name="gdraw_file_type" msgid="655688091676820371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎Google drawing‎‏‎‎‏‎"</string>
-    <string name="gtable_file_type" msgid="7332773878374650335">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎Google table‎‏‎‎‏‎"</string>
-    <string name="gform_file_type" msgid="4803176103746107611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎Google form‎‏‎‎‏‎"</string>
-    <string name="gmap_file_type" msgid="6684180781808007016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎Google map‎‏‎‎‏‎"</string>
-    <string name="gsite_file_type" msgid="3742812051249149526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎Google site‎‏‎‎‏‎"</string>
-    <string name="directory_type" msgid="2702987727566226354">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‎Folder‎‏‎‎‏‎"</string>
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="EXTENSION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ file‎‏‎‎‏‎"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎File‎‏‎‎‏‎"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎Image‎‏‎‎‏‎"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ image‎‏‎‎‏‎"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎Audio‎‏‎‎‏‎"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ audio‎‏‎‎‏‎"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎Video‎‏‎‎‏‎"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ video‎‏‎‎‏‎"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="FILETYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ archive‎‏‎‎‏‎"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎Android application‎‏‎‎‏‎"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎Plain text‎‏‎‎‏‎"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎HTML document‎‏‎‎‏‎"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎PDF document‎‏‎‎‏‎"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎Word document‎‏‎‎‏‎"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎PowerPoint presentation‎‏‎‎‏‎"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎Excel spreadsheet‎‏‎‎‏‎"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎Google document‎‏‎‎‏‎"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎Google spreadsheet‎‏‎‎‏‎"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎Google presentation‎‏‎‎‏‎"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎Google drawing‎‏‎‎‏‎"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎Google table‎‏‎‎‏‎"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎Google form‎‏‎‎‏‎"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎Google map‎‏‎‎‏‎"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎Google site‎‏‎‎‏‎"</string>
+    <string name="directory_type" msgid="2702987727566226354">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‎Folder‎‏‎‎‏‎"</string>
 </resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 9e727f9..8069fb9 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -16,194 +16,234 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="files_label" msgid="771781190045103748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎Files‎‏‎‎‏‎"</string>
-    <string name="downloads_label" msgid="5462789470049501103">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎Downloads‎‏‎‎‏‎"</string>
+    <string name="files_label" msgid="771781190045103748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎Files‎‏‎‎‏‎"</string>
+    <string name="downloads_label" msgid="5462789470049501103">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎Downloads‎‏‎‎‏‎"</string>
     <!-- no translation found for app_label (8089292432455111409) -->
     <skip />
     <!-- no translation found for launcher_label (799410258349837668) -->
     <skip />
-    <string name="title_open" msgid="3165686459158020921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎Open from‎‏‎‎‏‎"</string>
-    <string name="title_save" msgid="4384490653102710025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‎Save to‎‏‎‎‏‎"</string>
-    <string name="menu_create_dir" msgid="2413624798689091042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎New folder‎‏‎‎‏‎"</string>
-    <string name="menu_grid" msgid="1453636521731880680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎Grid view‎‏‎‎‏‎"</string>
-    <string name="menu_list" msgid="6714267452146410402">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎List view‎‏‎‎‏‎"</string>
-    <string name="menu_search" msgid="1876699106790719849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎Search‎‏‎‎‏‎"</string>
-    <string name="menu_settings" msgid="6520844520117939047">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎Storage settings‎‏‎‎‏‎"</string>
-    <string name="menu_open" msgid="9092138100049759315">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎Open‎‏‎‎‏‎"</string>
-    <string name="menu_open_with" msgid="5507647065467520229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎Open with‎‏‎‎‏‎"</string>
-    <string name="menu_open_in_new_window" msgid="6686563636123311276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎Open in new window‎‏‎‎‏‎"</string>
-    <string name="menu_save" msgid="5195367497138965168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎Save‎‏‎‎‏‎"</string>
-    <string name="menu_share" msgid="4307140947108068356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎Share‎‏‎‎‏‎"</string>
-    <string name="menu_delete" msgid="1022254131543256626">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎Delete‎‏‎‎‏‎"</string>
-    <string name="menu_select_all" msgid="7600576812185570403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎Select all‎‏‎‎‏‎"</string>
-    <string name="menu_copy" msgid="7404820171352314754">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎Copy to…‎‏‎‎‏‎"</string>
-    <string name="menu_move" msgid="2310760789561129882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎Move to…‎‏‎‎‏‎"</string>
-    <string name="menu_compress" msgid="37539111904724188">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎Compress‎‏‎‎‏‎"</string>
-    <string name="menu_extract" msgid="8171946945982532262">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎Extract to…‎‏‎‎‏‎"</string>
-    <string name="menu_rename" msgid="1883113442688817554">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎Rename‎‏‎‎‏‎"</string>
-    <string name="menu_inspect" msgid="7279855349299446224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎Get info‎‏‎‎‏‎"</string>
-    <string name="menu_view_in_owner" msgid="7228948660557554770">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎View in ‎‏‎‎‏‏‎<xliff:g id="SOURCE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="menu_new_window" msgid="2947837751796109126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎New window‎‏‎‎‏‎"</string>
-    <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎Cut‎‏‎‎‏‎"</string>
-    <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎Copy‎‏‎‎‏‎"</string>
-    <string name="menu_paste_from_clipboard" msgid="360947260414135827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎Paste‎‏‎‎‏‎"</string>
-    <string name="menu_paste_into_folder" msgid="8000644546983240101">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎Paste into folder‎‏‎‎‏‎"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎Show internal storage‎‏‎‎‏‎"</string>
-    <string name="menu_advanced_hide" msgid="6488381508009246334">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎Hide internal storage‎‏‎‎‏‎"</string>
-    <string name="button_select" msgid="240863497069321364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎Select‎‏‎‎‏‎"</string>
-    <string name="button_copy" msgid="8219059853840996027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎Copy‎‏‎‎‏‎"</string>
-    <string name="button_compress" msgid="8951561310857223966">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎Compress‎‏‎‎‏‎"</string>
-    <string name="button_extract" msgid="1038674453689912247">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎Extract‎‏‎‎‏‎"</string>
-    <string name="button_move" msgid="8596460499325291272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎Move‎‏‎‎‏‎"</string>
-    <string name="button_dismiss" msgid="7235249361023803349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎Dismiss‎‏‎‎‏‎"</string>
-    <string name="button_retry" msgid="4011461781916631389">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‎Try Again‎‏‎‎‏‎"</string>
-    <string name="button_clear" msgid="5412304437764369441">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎Clear‎‏‎‎‏‎"</string>
-    <string name="button_show_provider" msgid="6905880493806292753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎Show in provider‎‏‎‎‏‎"</string>
-    <string name="not_sorted" msgid="7813496644889115530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎Not sorted‎‏‎‎‏‎"</string>
-    <string name="sort_dimension_name" msgid="6325591541414177579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎Name‎‏‎‎‏‎"</string>
-    <string name="sort_dimension_summary" msgid="7724534446881397860">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎Summary‎‏‎‎‏‎"</string>
-    <string name="sort_dimension_file_type" msgid="5779709622922085381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎Type‎‏‎‎‏‎"</string>
-    <string name="sort_dimension_size" msgid="2190547351159472884">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎Size‎‏‎‎‏‎"</string>
-    <string name="sort_dimension_date" msgid="4231005651895254033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎Modified‎‏‎‎‏‎"</string>
-    <string name="directory_items" msgid="6645621978998614003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎Number of items‎‏‎‎‏‎"</string>
-    <string name="sort_direction_ascending" msgid="5882787683763248102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎Ascending‎‏‎‎‏‎"</string>
-    <string name="sort_direction_descending" msgid="1729187589765894076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎Descending‎‏‎‎‏‎"</string>
-    <string name="drawer_open" msgid="8071673398187261741">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎Show roots‎‏‎‎‏‎"</string>
-    <string name="drawer_close" msgid="4263880768630848848">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎Hide roots‎‏‎‎‏‎"</string>
-    <string name="save_error" msgid="8631128801982095782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‎‎Failed to save document‎‏‎‎‏‎"</string>
-    <string name="create_error" msgid="3092144450044861994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎Failed to create folder‎‏‎‎‏‎"</string>
-    <string name="query_error" msgid="6625421453613879336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎Can’t load content at the moment‎‏‎‎‏‎"</string>
-    <string name="root_recent" msgid="1080156975424341623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎Recent‎‏‎‎‏‎"</string>
-    <string name="root_available_bytes" msgid="8269870862691408864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SIZE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ free‎‏‎‎‏‎"</string>
-    <string name="root_type_service" msgid="6521366147466512289">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎Storage services‎‏‎‎‏‎"</string>
-    <string name="root_type_shortcut" msgid="6059343175525442279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎Shortcuts‎‏‎‎‏‎"</string>
-    <string name="root_type_device" msgid="1713604128005476585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎Devices‎‏‎‎‏‎"</string>
-    <string name="root_type_apps" msgid="8646073235029886342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎More apps‎‏‎‎‏‎"</string>
-    <string name="empty" msgid="5300254272613103004">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎No items‎‏‎‎‏‎"</string>
-    <string name="no_results" msgid="2371026325236359209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎No matches in %1$s‎‏‎‎‏‎"</string>
-    <string name="toast_no_application" msgid="7555319548595113121">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎Can’t open file‎‏‎‎‏‎"</string>
-    <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‎Cannot open files in archives‎‏‎‎‏‎"</string>
-    <string name="toast_failed_delete" msgid="3453846588205817591">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎Unable to delete some documents‎‏‎‎‏‎"</string>
-    <string name="share_via" msgid="8725082736005677161">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎Share via‎‏‎‎‏‎"</string>
-    <string name="copy_notification_title" msgid="52256435625098456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎Copying files‎‏‎‎‏‎"</string>
-    <string name="compress_notification_title" msgid="6830195148113751021">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‎Compressing files‎‏‎‎‏‎"</string>
-    <string name="extract_notification_title" msgid="5067393961754430469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‎Extracting files‎‏‎‎‏‎"</string>
-    <string name="move_notification_title" msgid="3173424987049347605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎Moving files‎‏‎‎‏‎"</string>
-    <string name="delete_notification_title" msgid="2512757431856830792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎Deleting files‎‏‎‎‏‎"</string>
-    <string name="copy_remaining" msgid="5390517377265177727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="DURATION">%s</xliff:g>‎‏‎‎‏‏‏‎ left‎‏‎‎‏‎"</string>
+    <string name="title_open" msgid="3165686459158020921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎Open from‎‏‎‎‏‎"</string>
+    <string name="title_save" msgid="4384490653102710025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‎Save to‎‏‎‎‏‎"</string>
+    <string name="menu_create_dir" msgid="2413624798689091042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎New folder‎‏‎‎‏‎"</string>
+    <string name="menu_grid" msgid="1453636521731880680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎Grid view‎‏‎‎‏‎"</string>
+    <string name="menu_list" msgid="6714267452146410402">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎List view‎‏‎‎‏‎"</string>
+    <string name="menu_search" msgid="1876699106790719849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎Search‎‏‎‎‏‎"</string>
+    <string name="menu_settings" msgid="6520844520117939047">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎Storage settings‎‏‎‎‏‎"</string>
+    <string name="menu_open" msgid="9092138100049759315">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎Open‎‏‎‎‏‎"</string>
+    <string name="menu_open_with" msgid="5507647065467520229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎Open with‎‏‎‎‏‎"</string>
+    <string name="menu_open_in_new_window" msgid="6686563636123311276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎Open in new window‎‏‎‎‏‎"</string>
+    <string name="menu_save" msgid="5195367497138965168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎Save‎‏‎‎‏‎"</string>
+    <string name="menu_share" msgid="4307140947108068356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎Share‎‏‎‎‏‎"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎Delete‎‏‎‎‏‎"</string>
+    <string name="menu_select_all" msgid="7600576812185570403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎Select all‎‏‎‎‏‎"</string>
+    <string name="menu_select" msgid="1366061076507142387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎Select‎‏‎‎‏‎"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎Sort by...‎‏‎‎‏‎"</string>
+    <string name="menu_copy" msgid="7404820171352314754">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎Copy to…‎‏‎‎‏‎"</string>
+    <string name="menu_move" msgid="2310760789561129882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎Move to…‎‏‎‎‏‎"</string>
+    <string name="menu_compress" msgid="37539111904724188">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎Compress‎‏‎‎‏‎"</string>
+    <string name="menu_extract" msgid="8171946945982532262">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎Extract to…‎‏‎‎‏‎"</string>
+    <string name="menu_rename" msgid="1883113442688817554">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎Rename‎‏‎‎‏‎"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎Get info‎‏‎‎‏‎"</string>
+    <string name="menu_view_in_owner" msgid="7228948660557554770">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎View in ‎‏‎‎‏‏‎<xliff:g id="SOURCE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="menu_new_window" msgid="2947837751796109126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎New window‎‏‎‎‏‎"</string>
+    <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎Cut‎‏‎‎‏‎"</string>
+    <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎Copy‎‏‎‎‏‎"</string>
+    <string name="menu_paste_from_clipboard" msgid="360947260414135827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎Paste‎‏‎‎‏‎"</string>
+    <string name="menu_paste_into_folder" msgid="8000644546983240101">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎Paste into folder‎‏‎‎‏‎"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎Show internal storage‎‏‎‎‏‎"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎Hide internal storage‎‏‎‎‏‎"</string>
+    <string name="button_select" msgid="240863497069321364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎Select‎‏‎‎‏‎"</string>
+    <string name="button_copy" msgid="8219059853840996027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎Copy‎‏‎‎‏‎"</string>
+    <string name="button_compress" msgid="8951561310857223966">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎Compress‎‏‎‎‏‎"</string>
+    <string name="button_extract" msgid="1038674453689912247">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎Extract‎‏‎‎‏‎"</string>
+    <string name="button_move" msgid="8596460499325291272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎Move‎‏‎‎‏‎"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎Dismiss‎‏‎‎‏‎"</string>
+    <string name="button_retry" msgid="4011461781916631389">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‎Try Again‎‏‎‎‏‎"</string>
+    <string name="button_clear" msgid="5412304437764369441">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎Clear‎‏‎‎‏‎"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎Show in provider‎‏‎‎‏‎"</string>
+    <string name="not_sorted" msgid="7813496644889115530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎Not sorted‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_name" msgid="6325591541414177579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎Name‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_summary" msgid="7724534446881397860">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎Summary‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_file_type" msgid="5779709622922085381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎Type‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_size" msgid="2190547351159472884">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎Size‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎Modified‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‎File name (A to Z)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Type (A to Z)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎Size (smallest first)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎Modified (oldest first)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‏‎‎File name (Z to A)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎Type (Z to A)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎Size (largest first)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎Modified (newest first)‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‏‎Sort by‎‏‎‎‏‎"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎Sorted by ‎‏‎‎‏‏‎<xliff:g id="LABEL">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="directory_items" msgid="6645621978998614003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎Number of items‎‏‎‎‏‎"</string>
+    <string name="sort_direction_ascending" msgid="5882787683763248102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎Ascending‎‏‎‎‏‎"</string>
+    <string name="sort_direction_descending" msgid="1729187589765894076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎Descending‎‏‎‎‏‎"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎Open ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="drawer_open" msgid="8071673398187261741">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎Show roots‎‏‎‎‏‎"</string>
+    <string name="drawer_close" msgid="4263880768630848848">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎Hide roots‎‏‎‎‏‎"</string>
+    <string name="save_error" msgid="8631128801982095782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‎‎Failed to save document‎‏‎‎‏‎"</string>
+    <string name="create_error" msgid="3092144450044861994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎Failed to create folder‎‏‎‎‏‎"</string>
+    <string name="query_error" msgid="6625421453613879336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎Can’t load content at the moment‎‏‎‎‏‎"</string>
+    <string name="root_recent" msgid="1080156975424341623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎Recent‎‏‎‎‏‎"</string>
+    <string name="root_available_bytes" msgid="8269870862691408864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SIZE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ free‎‏‎‎‏‎"</string>
+    <string name="root_type_service" msgid="6521366147466512289">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎Storage services‎‏‎‎‏‎"</string>
+    <string name="root_type_shortcut" msgid="6059343175525442279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎Shortcuts‎‏‎‎‏‎"</string>
+    <string name="root_type_device" msgid="1713604128005476585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎Devices‎‏‎‎‏‎"</string>
+    <string name="root_type_apps" msgid="8646073235029886342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎More apps‎‏‎‎‏‎"</string>
+    <string name="empty" msgid="5300254272613103004">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎No items‎‏‎‎‏‎"</string>
+    <string name="no_results" msgid="2371026325236359209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎No matches in %1$s‎‏‎‎‏‎"</string>
+    <string name="toast_no_application" msgid="7555319548595113121">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎Can’t open file‎‏‎‎‏‎"</string>
+    <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‎Cannot open files in archives‎‏‎‎‏‎"</string>
+    <string name="toast_failed_delete" msgid="3453846588205817591">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎Unable to delete some documents‎‏‎‎‏‎"</string>
+    <string name="share_via" msgid="8725082736005677161">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎Share via‎‏‎‎‏‎"</string>
+    <string name="copy_notification_title" msgid="52256435625098456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎Copying files‎‏‎‎‏‎"</string>
+    <string name="compress_notification_title" msgid="6830195148113751021">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‎Compressing files‎‏‎‎‏‎"</string>
+    <string name="extract_notification_title" msgid="5067393961754430469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‎Extracting files‎‏‎‎‏‎"</string>
+    <string name="move_notification_title" msgid="3173424987049347605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎Moving files‎‏‎‎‏‎"</string>
+    <string name="delete_notification_title" msgid="2512757431856830792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎Deleting files‎‏‎‎‏‎"</string>
+    <string name="copy_remaining" msgid="5390517377265177727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="DURATION">%s</xliff:g>‎‏‎‎‏‏‏‎ left‎‏‎‎‏‎"</string>
     <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎Copying ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎Copying ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎Copying ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎Copying ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="compress_begin" formatted="false" msgid="3534158317098678895">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎Compressing ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎Compressing ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file.‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎Compressing ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎Compressing ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file.‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="extract_begin" formatted="false" msgid="1006380679562903749">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎Extracting ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎Extracting ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file.‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎Extracting ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎Extracting ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file.‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎Moving ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎Moving ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎Moving ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎Moving ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="deleting" formatted="false" msgid="1729138001178158901">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎Deleting ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎Deleting ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎Deleting ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎Deleting ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item.‎‏‎‎‏‎</item>
     </plurals>
-    <string name="undo" msgid="2902438994196400565">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎Undo‎‏‎‎‏‎"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎Preparing for copy…‎‏‎‎‏‎"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎Preparing for compress…‎‏‎‎‏‎"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎Preparing for extract…‎‏‎‎‏‎"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎Preparing for move…‎‏‎‎‏‎"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎Preparing for delete…‎‏‎‎‏‎"</string>
-    <string name="delete_progress" msgid="2627631054702306423">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎<xliff:g id="TOTALCOUNT">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="undo" msgid="2902438994196400565">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎Undo‎‏‎‎‏‎"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎Preparing...‎‏‎‎‏‎"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎Preparing...‎‏‎‎‏‎"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎Preparing...‎‏‎‎‏‎"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎Preparing...‎‏‎‎‏‎"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‎Preparing...‎‏‎‎‏‎"</string>
+    <string name="delete_progress" msgid="2627631054702306423">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎<xliff:g id="TOTALCOUNT">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎Couldn’t copy ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎Couldn’t copy ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎Couldn’t copy ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎Couldn’t copy ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="compress_error_notification_title" formatted="false" msgid="3043630066678213644">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Couldn’t compress ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Couldn’t compress ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Couldn’t compress ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Couldn’t compress ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="move_error_notification_title" formatted="false" msgid="2185736082411854754">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎Couldn’t move ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎Couldn’t move ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎Couldn’t move ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎Couldn’t move ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="delete_error_notification_title" formatted="false" msgid="7568122018481625267">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎Couldn’t delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎Couldn’t delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎Couldn’t delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎Couldn’t delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="2385563502445129570">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎Tap to view details‎‏‎‎‏‎"</string>
-    <string name="close" msgid="905969391788869975">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‎Close‎‏‎‎‏‎"</string>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎Tap to view details‎‏‎‎‏‎"</string>
+    <string name="close" msgid="905969391788869975">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‎Close‎‏‎‎‏‎"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎These files weren’t copied: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎This file wasn’t copied: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎These files weren’t copied: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎This file wasn’t copied: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="compress_failure_alert_content" formatted="false" msgid="5760632881868842400">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎These files weren’t compressed: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎This file wasn’t compressed: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎These files weren’t compressed: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎This file wasn’t compressed: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="extract_failure_alert_content" formatted="false" msgid="7572748127571720803">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎These files weren’t extracted: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎This file wasn’t extracted: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎These files weren’t extracted: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎This file wasn’t extracted: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="move_failure_alert_content" formatted="false" msgid="2747390342670799196">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎These files weren’t moved: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎This file wasn’t moved: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎These files weren’t moved: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎This file wasn’t moved: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="delete_failure_alert_content" formatted="false" msgid="6122372614839711711">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎These files weren’t deleted: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎This file wasn’t deleted: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎These files weren’t deleted: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎This file wasn’t deleted: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎These files were converted to another format: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎This file was converted to another format: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎These files were converted to another format: ‎‏‎‎‏‏‎<xliff:g id="LIST_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎This file was converted to another format: ‎‏‎‎‏‏‎<xliff:g id="LIST_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Copied ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items to clipboard.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Copied ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item to clipboard.‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Copied ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items to clipboard.‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎Copied ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item to clipboard.‎‏‎‎‏‎</item>
     </plurals>
-    <string name="file_operation_rejected" msgid="4301554203329008794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎File operation is not supported.‎‏‎‎‏‎"</string>
-    <string name="file_operation_error" msgid="2234357335716533795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎File operation failed.‎‏‎‎‏‎"</string>
-    <string name="rename_error" msgid="6700093173508118635">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎Failed to rename document‎‏‎‎‏‎"</string>
-    <string name="menu_eject_root" msgid="9215040039374893613">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎Eject‎‏‎‎‏‎"</string>
-    <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎Some files were converted‎‏‎‎‏‎"</string>
-    <string name="open_external_dialog_request" msgid="8173558471322861268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to ‎‏‎‎‏‏‎<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎ directory on ‎‏‎‎‏‏‎<xliff:g id="STORAGE"><i>^3</i></xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to ‎‏‎‎‏‏‎<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎ directory?‎‏‎‎‏‎"</string>
-    <string name="open_external_dialog_root_request" msgid="6776729293982633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to your data, including photos and videos, on ‎‏‎‎‏‏‎<xliff:g id="STORAGE"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎Don\'t ask again‎‏‎‎‏‎"</string>
-    <string name="allow" msgid="1275746941353040309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎Allow‎‏‎‎‏‎"</string>
-    <string name="deny" msgid="5127201668078153379">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎Deny‎‏‎‎‏‎"</string>
+    <string name="file_operation_rejected" msgid="4301554203329008794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎File operation is not supported.‎‏‎‎‏‎"</string>
+    <string name="file_operation_error" msgid="2234357335716533795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎File operation failed.‎‏‎‎‏‎"</string>
+    <string name="rename_error" msgid="6700093173508118635">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎Failed to rename document‎‏‎‎‏‎"</string>
+    <string name="menu_eject_root" msgid="9215040039374893613">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎Eject‎‏‎‎‏‎"</string>
+    <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎Some files were converted‎‏‎‎‏‎"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to ‎‏‎‎‏‏‎<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎ directory on ‎‏‎‎‏‏‎<xliff:g id="STORAGE"><i>^3</i></xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to ‎‏‎‎‏‏‎<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎ directory?‎‏‎‎‏‎"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎Grant ‎‏‎‎‏‏‎<xliff:g id="APPNAME"><b>^1</b></xliff:g>‎‏‎‎‏‏‏‎ access to your data, including photos and videos, on ‎‏‎‎‏‏‎<xliff:g id="STORAGE"><i>^2</i></xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="allow" msgid="1275746941353040309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎Allow‎‏‎‎‏‎"</string>
+    <string name="deny" msgid="5127201668078153379">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎Deny‎‏‎‎‏‎"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item‎‏‎‎‏‎</item>
     </plurals>
-    <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎Delete \"‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\"?‎‏‎‎‏‎"</string>
-    <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‎‎Delete folder \"‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\" and its contents?‎‏‎‎‏‎"</string>
+    <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎Delete \"‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\"?‎‏‎‎‏‎"</string>
+    <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‎‎Delete folder \"‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\" and its contents?‎‏‎‎‏‎"</string>
     <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files?‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file?‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ files?‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ file?‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ folders and their contents?‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ folder and its contents?‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ folders and their contents?‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ folder and its contents?‎‏‎‎‏‎</item>
     </plurals>
     <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items?‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item?‎‏‎‎‏‎</item>
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ items?‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎Delete ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ item?‎‏‎‎‏‎</item>
     </plurals>
-    <string name="images_shortcut_label" msgid="2545168016070493574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎Images‎‏‎‎‏‎"</string>
-    <string name="archive_loading_failed" msgid="7243436722828766996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎Unable to open archive for browsing. File is either corrupt, or an unsupported format.‎‏‎‎‏‎"</string>
-    <string name="name_conflict" msgid="28407269328862986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎A file with this name already exists.‎‏‎‎‏‎"</string>
-    <string name="authentication_required" msgid="8030880723643436099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎To view this directory, sign in to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="cant_display_content" msgid="8633226333229417237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎Can’t display contents‎‏‎‎‏‎"</string>
-    <string name="sign_in" msgid="6253762676723505592">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎Sign in‎‏‎‎‏‎"</string>
-    <string name="new_archive_file_name" msgid="1604650338077249838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎archive‎‏‎‎‏‏‎<xliff:g id="EXTENSION">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎Overwrite ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <string name="continue_in_background" msgid="1974214559047793331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎Continue in background‎‏‎‎‏‎"</string>
+    <string name="images_shortcut_label" msgid="2545168016070493574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎Images‎‏‎‎‏‎"</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎Unable to open archive for browsing. File is either corrupt, or an unsupported format.‎‏‎‎‏‎"</string>
+    <string name="name_conflict" msgid="28407269328862986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎A file with this name already exists.‎‏‎‎‏‎"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎To view this directory, sign in to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎Can’t display contents‎‏‎‎‏‎"</string>
+    <string name="sign_in" msgid="6253762676723505592">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎Sign in‎‏‎‎‏‎"</string>
+    <string name="new_archive_file_name" msgid="1604650338077249838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎archive‎‏‎‎‏‏‎<xliff:g id="EXTENSION">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎Overwrite ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="continue_in_background" msgid="1974214559047793331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎Continue in background‎‏‎‎‏‎"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
+      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎Recent files on phone‎‏‎‎‏‎"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‎Files on phone‎‏‎‎‏‎"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ on phone‎‏‎‎‏‎"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎Files on ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎Files from ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎Files from ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎<xliff:g id="SUMMARY">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎Recent images on phone‎‏‎‎‏‎"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎Images on phone‎‏‎‎‏‎"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎Images on ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‎Images from ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎Images from ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎<xliff:g id="SUMMARY">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎Images‎‏‎‎‏‎"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎Audio‎‏‎‎‏‎"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎Videos‎‏‎‎‏‎"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎Documents‎‏‎‎‏‎"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎Folder name‎‏‎‎‏‎"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎New name‎‏‎‎‏‎"</string>
+    <string name="preview_file" msgid="4056622696305432343">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎Preview the file ‎‏‎‎‏‏‎<xliff:g id="FILENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎Browse files in other apps‎‏‎‎‏‎"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎Anonymous‎‏‎‎‏‎"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎Allow access to \"‎‏‎‎‏‏‎<xliff:g id="DIRECTORY">%1$s</xliff:g>‎‏‎‎‏‏‏‎\"‎‏‎‎‏‎"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎Allow access to \"‎‏‎‎‏‏‎<xliff:g id="DIRECTORY">%1$s</xliff:g>‎‏‎‎‏‏‏‎\" on \"‎‏‎‎‏‏‎<xliff:g id="ROOT">%2$s</xliff:g>‎‏‎‎‏‏‏‎\"?‎‏‎‎‏‎"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎It will allow \"‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎\" to have full access to all files currently stored under this location, and any future content stored here.‎‏‎‎‏‎"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‎Search this phone‎‏‎‎‏‎"</string>
 </resources>
diff --git a/res/values-es-rUS/config.xml b/res/values-es-rUS/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-es-rUS/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 07d660e..6acaf45 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Compartir"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Borrar"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Seleccionar todos"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Seleccionar"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordenar por…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiar a…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Mover a…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaño"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificación"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nombre (A-Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (A-Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamaño (más pequeños)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Más antiguos primero"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nombre (Z-A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (Z-A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamaño (más grandes)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Más recientes primero"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordenar por"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Se ordena por <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Cantidad de elementos"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raíces"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ocultar raíces"</string>
     <string name="save_error" msgid="8631128801982095782">"Error al guardar el documento"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Borrando <xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Deshacer"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparando para copiar…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparando la compresión…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparando para la extracción…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparación para mover archivos…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparando para borrar…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparando…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparando…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparando…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparando…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparando…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">No se pudieron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"¿Quieres otorgar a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceso al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> en <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"¿Quieres otorgar acceso a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"¿Quieres otorgar acceso a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> a tus datos, incluidas tus fotos y videos, en <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"No volver a preguntar"</string>
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Rechazar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archivo<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"¿Deseas sobrescribir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuar en segundo plano"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos seleccionados</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento seleccionado</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Archivos recientes en el teléfono"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Archivos en el teléfono"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> en el teléfono"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Archivos en <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Archivos de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Archivos de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imágenes recientes en el teléfono"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imágenes en el teléfono"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imágenes en <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imágenes de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imágenes de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imágenes"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documentos"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nombre de carpeta"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nombre nuevo"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Obtener vista previa del archivo <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Explorar archivos en otras apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anónimo"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permitir el acceso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"¿Permitir el acceso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" en \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Le permitirá a \"<xliff:g id="APPNAME">%1$s</xliff:g>\" tener acceso completo a todos los archivos almacenados actualmente en esta ubicación y a cualquier contenido que se almacene aquí en el futuro."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Buscar en este teléfono"</string>
 </resources>
diff --git a/res/values-es/config.xml b/res/values-es/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-es/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 636df57..1a12e8c 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Compartir"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Eliminar"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Seleccionar todo"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Seleccionar"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordenar por..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiar en…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Mover a…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
@@ -55,7 +57,7 @@
     <string name="button_compress" msgid="8951561310857223966">"Comprimir"</string>
     <string name="button_extract" msgid="1038674453689912247">"Extraer"</string>
     <string name="button_move" msgid="8596460499325291272">"Mover"</string>
-    <string name="button_dismiss" msgid="7235249361023803349">"Descartar"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"Cerrar"</string>
     <string name="button_retry" msgid="4011461781916631389">"Volver a intentarlo"</string>
     <string name="button_clear" msgid="5412304437764369441">"Borrar"</string>
     <string name="button_show_provider" msgid="6905880493806292753">"Mostrar en el proveedor"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaño"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nombre de archivo (A‑Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (A‑Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamaño (de menor a mayor)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Fecha de edición (de menos a más reciente)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nombre de archivo (Z‑A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (Z‑A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamaño (de mayor a menor)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Fecha de edición (de más a menos reciente)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordenar por"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Ordenados por <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Número de elementos"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raíces"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ocultar raíces"</string>
     <string name="save_error" msgid="8631128801982095782">"No se ha podido guardar el documento"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Eliminando <xliff:g id="COUNT_0">%1$d</xliff:g> elemento.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Deshacer"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparando para copiar..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparando para comprimir…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparando para extracción…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparando para mover…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparando para eliminar…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparando..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparando..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparando..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparando..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparando..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">No se han podido copiar <xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda a tus datos de <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incluidos los vídeos y las fotos?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"No volver a preguntar"</string>
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Denegar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archivo<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"¿Sobrescribir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuar en segundo plano"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seleccionados</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seleccionado</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Archivos recientes del teléfono"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Archivos del teléfono"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> en el teléfono"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Archivos de <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Archivos de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Archivos de <xliff:g id="LABEL">%1$s</xliff:g> (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imágenes recientes del teléfono"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imágenes del teléfono"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imágenes del <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imágenes de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imágenes de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imágenes"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documentos"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nombre de la carpeta"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nombre nuevo"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Obtener una vista previa del archivo <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Consultar archivos en otras aplicaciones"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anónimo"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permitir acceso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"De este modo, la aplicación \"<xliff:g id="APPNAME">%1$s</xliff:g>\" podrá acceder a todos los archivos almacenados en esta ubicación y al contenido que se almacene en ella en el futuro."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Buscar este teléfono"</string>
 </resources>
diff --git a/res/values-et/config.xml b/res/values-et/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-et/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index e86fcd5..825d9e7 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Jaga"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Kustuta"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Vali kõik"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Vali"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortimisalus …"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopeeri asukohta …"</string>
     <string name="menu_move" msgid="2310760789561129882">"Teisalda asukohta …"</string>
     <string name="menu_compress" msgid="37539111904724188">"Tihenda"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tüüp"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Suurus"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Muudetud"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Faili nimi (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tüüp (A–Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Suurus (väikseimad enne)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Muudetud (vanimad enne)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Faili nimi (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tüüp (Z–A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Suurus (suurimad enne)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Muudetud (uusimad enne)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortimisalus:"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sortimisalus: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Üksuste arv"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Kasvav"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Kahanev"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> avamine"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Kuva juured"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Peida juured"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokumendi salvestamine ebaõnnestus"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Kustutatakse <xliff:g id="COUNT_0">%1$d</xliff:g> üksus.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Võta tagasi"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopeerimise ettevalmistamine …"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Tihendamiseks ettevalmistamine …"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Ekstraktimise ettevalmistamine …"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Teisaldamise ettevalmistamine …"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Kustutamise ettevalmistamine …"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Ettevalmistamine …"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Ettevalmistamine …"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Ettevalmistamine …"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Ettevalmistamine …"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Ettevalmistamine …"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> üksust ei saanud kopeerida</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> salvestusruumis <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs teie andmetele (sh fotod ja videod) salvestusruumis <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ära enam küsi"</string>
     <string name="allow" msgid="1275746941353040309">"Luba"</string>
     <string name="deny" msgid="5127201668078153379">"Keela"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhiiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Kas kirjutada üle üksus <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Jätka taustal"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">Valitud on <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Valitud on <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Hiljutised failid telefonis"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Telefonis olevad failid"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> telefonis"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Seadmes <xliff:g id="DEVICE">%1$s</xliff:g> olevad failid"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Failid teenusest <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Failid teenusest <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Telefonis olevad hiljutised pildid"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Telefonis olevad pildid"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Pildid seadmes <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Pildid asukohast <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Pildid asukohast <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Pildid"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Heli"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videod"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumendid"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Kausta nimi"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Uus nimi"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Faili <xliff:g id="FILENAME">%1$s</xliff:g> eelvaade"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Failide sirvimine muudes rakendustes"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonüümne"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Luba juurdepääs kataloogile „<xliff:g id="DIRECTORY">%1$s</xliff:g>”"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Kas lubada juurdepääs kataloogile „<xliff:g id="DIRECTORY">%1$s</xliff:g>” juurkataloogis „<xliff:g id="ROOT">%2$s</xliff:g>”?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"See annab rakendusele „<xliff:g id="APPNAME">%1$s</xliff:g>” täieliku juurdepääsu kõigile failidele, mis praegu sellesse asukohta on salvestatud (ja muule tulevikus siia salvestatavale sisule)."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Otsi seda telefoni"</string>
 </resources>
diff --git a/res/values-eu/config.xml b/res/values-eu/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-eu/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-eu/inspector_strings.xml b/res/values-eu/inspector_strings.xml
index 24b9b4a..9f51a8c 100644
--- a/res/values-eu/inspector_strings.xml
+++ b/res/values-eu/inspector_strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="inspector_title" msgid="1924760928091740238">"Informazioa"</string>
     <string name="inspector_load_error" msgid="7522190243413249291">"Ezin izan da kargatu fitxategiaren informazioa"</string>
-    <string name="inspector_debug_section" msgid="2576052661505700421">"Arazte-informazioa (garatzaileentzat soilik)"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"Arazketa-informazioa (garatzaileentzat soilik)"</string>
     <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"Prozesatu gabeko metadatuak: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
     <string name="inspector_metadata_section" msgid="6077622515328240575">"Multimedia-elementuaren xehetasunak"</string>
     <string name="handler_app_file_opens_with" msgid="5272329600389613550">"Mota honetako fitxategiak aplikazio honekin ireki daitezke:"</string>
diff --git a/res/values-eu/mimes.xml b/res/values-eu/mimes.xml
index 45294b7..d5768f2 100644
--- a/res/values-eu/mimes.xml
+++ b/res/values-eu/mimes.xml
@@ -40,6 +40,6 @@
     <string name="gtable_file_type" msgid="7332773878374650335">"Google taula"</string>
     <string name="gform_file_type" msgid="4803176103746107611">"Google inprimakia"</string>
     <string name="gmap_file_type" msgid="6684180781808007016">"Google mapa"</string>
-    <string name="gsite_file_type" msgid="3742812051249149526">"Google webgunea"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google-ren webgunea"</string>
     <string name="directory_type" msgid="2702987727566226354">"Karpeta"</string>
 </resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 7c3deee..60201de 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Partekatu"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Ezabatu"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Hautatu guztiak"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Hautatu"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordenatzeko irizpidea…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiatu hemen…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Eraman hona…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Konprimatu"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Mota"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Aldatze-ordua"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Fitxategi-izena (A-Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Mota (A-Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamaina (txikienetik)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Aldatze-data (zaharrenetik)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Fitxategi-izena (Z-A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Mota (Z-A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamaina (handienetik)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Aldatze-data (berrienetik)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordenatzeko irizpidea"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Ordena: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Elementu kopurua"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Gorantz"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Beherantz"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Erakutsi erroko karpetak"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ezkutatu erroko karpetak"</string>
     <string name="save_error" msgid="8631128801982095782">"Ezin izan da gorde dokumentua"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elementu ezabatzen.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Desegin"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopiatzeko prestatzen…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Konprimatzeko prestatzen…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Ateratzeko prestatzen…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Mugitzeko prestatzen…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Ezabatzeko prestatzen…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Prestatzen…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Prestatzen…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Prestatzen…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Prestatzen…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Prestatzen…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Ezin izan dira kopiatu <xliff:g id="COUNT_1">%1$d</xliff:g> elementu</item>
@@ -169,10 +182,9 @@
     <string name="rename_error" msgid="6700093173508118635">"Ezin izan zaio aldatu izena dokumentuari"</string>
     <string name="menu_eject_root" msgid="9215040039374893613">"Atera"</string>
     <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"Artxibo batzuk bihurtu dira"</string>
-    <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktorioa atzitzeko baimena eman nahi diozu?"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktoriorako sarbidea eman nahi diozu?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktoriorako sarbidea eman nahi diozu?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari zure datuak atzitzea baimendu nahi diozu, besteak beste, <xliff:g id="STORAGE"><i>^2</i></xliff:g> biltegian dituzun argazkiak eta bideoak?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ez galdetu berriro"</string>
     <string name="allow" msgid="1275746941353040309">"Baimendu"</string>
     <string name="deny" msgid="5127201668078153379">"Ukatu"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"artxiboa<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> gainidatzi nahi duzu?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Jarraitu atzeko planoan"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> hautatuta</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Telefonoko azken fitxategiak"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Telefonoko fitxategiak"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Telefonoko <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> gailuko fitxategiak"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> zerbitzuko fitxategiak"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> zerbitzuko fitxategiak / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Telefonoko azken irudiak"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Telefonoko irudiak"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> gailuko irudiak"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> zerbitzuko irudiak"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g> kokapeneko irudiak"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Irudiak"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audioa"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Bideoak"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumentuak"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Karpetaren izena"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Izen berria"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Aurreikusi <xliff:g id="FILENAME">%1$s</xliff:g> fitxategia"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Arakatu beste aplikazio batzuetako fitxategiak"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonimoa"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Eman \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" direktorioan sartzeko baimena"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Hemen biltegiratuta dauden fitxategi guztietan sartzeko baimen osoa emango dio \"<xliff:g id="APPNAME">%1$s</xliff:g>\" aplikazioari, baita etorkizunean biltegiratuko den edukirako ere."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Bilatu telefono hau"</string>
 </resources>
diff --git a/res/values-fa/config.xml b/res/values-fa/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-fa/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 5417179..67f5f84 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"اشتراک‌گذاری"</string>
     <string name="menu_delete" msgid="1022254131543256626">"حذف"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"انتخاب همه"</string>
+    <string name="menu_select" msgid="1366061076507142387">"انتخاب"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"مرتب کردن براساس..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"کپی در..."</string>
     <string name="menu_move" msgid="2310760789561129882">"انتقال به…"</string>
     <string name="menu_compress" msgid="37539111904724188">"فشرده کردن"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"نوع"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"اندازه"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"آخرین تغییر"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"‏نام فایل (A تا Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"‏نوع (A تا Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"اندازه (ابتدا کوچک‌ترین)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"اصلاح‌شده (ابتدا قدیمی‌ترین)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"‏نام فایل (Z تا A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"‏نوع (Z تا A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"اندازه (ابتدا بزرگ‌ترین)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"اصلاح‌شده (ابتدا جدید‌ترین)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"مرتب کردن براساس"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"مرتب‌شده براساس <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"تعداد موارد"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"صعودی"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"نزولی"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"باز کردن <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"نمایش ریشه‌ها"</string>
     <string name="drawer_close" msgid="4263880768630848848">"پنهان کردن ریشه‌ها"</string>
     <string name="save_error" msgid="8631128801982095782">"سند ذخیره نشد"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">درحال حذف <xliff:g id="COUNT_1">%1$d</xliff:g> مورد.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"واگرد"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"در حال آماده‌سازی برای کپی..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"آماده شدن برای فشرده‌سازی…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"درحال آماده‌سازی برای استخراج…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"درحال آماده‌سازی برای انتقال…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"درحال آماده‌سازی برای حذف…‏"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"در حال آماده‌سازی..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"در حال آماده‌سازی..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"در حال آماده‌سازی..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"در حال آماده‌سازی..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"در حال آماده‌سازی..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> مورد کپی نشد</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه داده شود به فهرست راهنمای <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> در <xliff:g id="STORAGE"><i>^3</i></xliff:g> دسترسی داشته باشد؟"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه داده شود به فهرست راهنمای <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> دسترسی داشته باشد؟"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه می‌دهید به داده‌هایتان دسترسی پیدا کند، از جمله عکس‌ها و ویدئوهایتان در <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"دوباره سؤال نشود"</string>
     <string name="allow" msgid="1275746941353040309">"اجازه دادن"</string>
     <string name="deny" msgid="5127201668078153379">"اجازه ندارد"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"بایگانی <xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> رونویسی شود؟"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ادامه در پس‌زمینه"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">‏<xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item>
+      <item quantity="other">‏<xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"فایل‌های اخیر موجود در تلفن"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"فایل‌های موجود در تلفن"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> در تلفن"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"فایل‌های موجود در <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"فایل‌های <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"فایل‌های <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"تصاویر اخیر موجود در تلفن"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"تصاویر موجود در تلفن"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"تصاویر موجود در <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"تصاویری از <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"تصاویری از <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"تصاویر"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"صدا"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ویدیوها"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"اسناد"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"نام پوشه"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"نام جدید"</string>
+    <string name="preview_file" msgid="4056622696305432343">"پیش‌نمایش فایل <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"مرور فایل‌ها در سایر برنامه‌ها"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ناشناس"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"اجازه دسترسی به «<xliff:g id="DIRECTORY">%1$s</xliff:g>»"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"اجازه دسترسی به «<xliff:g id="DIRECTORY">%1$s</xliff:g>» در «<xliff:g id="ROOT">%2$s</xliff:g>» داده شود؟"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"این کار به «<xliff:g id="APPNAME">%1$s</xliff:g>» اجازه می‌دهد به‌طور کامل به تمام فایل‌هایی که درحال‌حاضر در این مکان ذخیره شده‌ است و هر محتوایی که در آینده در اینجا ذخیره می‌شود دسترسی داشته باشد."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"جستجوی این تلفن"</string>
 </resources>
diff --git a/res/values-fi/config.xml b/res/values-fi/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-fi/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index a23dd94..3ae98c2 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Jaa"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Poista"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Valitse kaikki"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Valitse"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Lajitteluperuste…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopioi kohteeseen…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Siirrä kohteeseen…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Pakkaa"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tyyppi"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Koko"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Muokattu"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Tiedostonimi (A–Ö)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tyyppi (A–Ö)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Koko (pienin ensin)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Muokattu (vanhin ensin)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Tiedostonimi (Ö–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tyyppi (Ö–A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Koko (suurin ensin)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Muokattu (uusin ensin)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Lajittelu"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Lajitteluperuste: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Kohteiden määrä"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Nouseva"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Laskeva"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Avaa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Näytä juuret"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Piilota juuret"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokumentin tallennus epäonnistui."</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Poistetaan <xliff:g id="COUNT_0">%1$d</xliff:g> kohde.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Kumoa"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Valmistellaan kopiointia…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Valmistaudutaan pakkaamiseen…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Valmistellaan purkamista…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Valmistellaan siirtämistä…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Valmistellaan poistamista…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Valmistellaan…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Valmistellaan…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Valmistellaan…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Valmistellaan…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Valmistellaan…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kohteen kopiointi epäonnistui.</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^3</i></xliff:g> olevan hakemiston <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> käyttöoikeus?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Saako <xliff:g id="APPNAME"><b>^1</b></xliff:g> käyttää hakemistoa <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^2</i></xliff:g> olevien tietojesi (mukaan lukien valokuvien ja videoiden) käyttöoikeus?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Älä kysy uudelleen"</string>
     <string name="allow" msgid="1275746941353040309">"Salli"</string>
     <string name="deny" msgid="5127201668078153379">"Estä"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arkisto<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Korvataanko <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Jatka taustalla"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valittu</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> valittu</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Puhelimen viimeaikaiset tiedostot"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Tiedostot puhelimessa"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> puhelimessa"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Tiedostot: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Tiedostot: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Tiedostot: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Puhelimen viimeaikaiset kuvat"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Puhelimen kuvat"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Kuvat: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Kuvat: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Kuvat: <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Kuvat"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Ääni"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videot"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumentit"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Kansion nimi"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Uusi nimi"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Esikatsele tiedostoa <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Selaa tiedostoja muissa sovelluksissa"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonyymi"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Myönnä käyttöoikeus: <xliff:g id="DIRECTORY">%1$s</xliff:g>"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Haluatko, että <xliff:g id="DIRECTORY">%1$s</xliff:g> saa käyttöoikeuden (<xliff:g id="ROOT">%2$s</xliff:g>)?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Sen avulla <xliff:g id="APPNAME">%1$s</xliff:g> saa täydet käyttöoikeudet kaikkiin tiedostoihin, jotka on tällä hetkellä tallennettu tähän sijaintiin, sekä tänne jatkossa tallennettavaan sisältöön."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Hae tältä puhelimelta"</string>
 </resources>
diff --git a/res/values-fr-rCA/config.xml b/res/values-fr-rCA/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-fr-rCA/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 66a68fb..e1b2431 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Partager"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Supprimer"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Tout sélectionner"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Sélectionner"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Trier par…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copier dans…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Déplacer dans…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compresser"</string>
@@ -48,7 +50,7 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Copier"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Coller"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"Coller dans le dossier"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"Aff. mém. stock. interne"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Aff. mémoire stockage int."</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"Masquer mém. stock. int."</string>
     <string name="button_select" msgid="240863497069321364">"Sélectionner"</string>
     <string name="button_copy" msgid="8219059853840996027">"Copier"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Taille"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Dernière modification"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nom de fichier (A à Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A à Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Taille (plus petit en 1er)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modif. (plus anc. en 1er)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nom de fichier (Z à A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z à A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Taille (plus gros en 1er)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modif. (plus réc. en 1er)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Trier par"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Trié par <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Nombre d\'éléments"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Par ordre croissant"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Par ordre décroissant"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Afficher les racines"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Masquer les racines"</string>
     <string name="save_error" msgid="8631128801982095782">"Échec de l\'enregistrement du document"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> éléments en cours.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Annuler"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Préparation de la copie en cours"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Préparation de la compression en cours…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Préparation pour l\'extraction…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Préparation du déplacement…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Préparation de la suppression…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Préparation en cours…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Préparation en cours…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Préparation en cours…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Préparation en cours…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Préparation en cours…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> sur <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> élément</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sur <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Voulez-vous accorder l\'accès à vos données à <xliff:g id="APPNAME"><b>^1</b></xliff:g>, y compris vos photos et vos vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ne plus demander"</string>
     <string name="allow" msgid="1275746941353040309">"Autoriser"</string>
     <string name="deny" msgid="5127201668078153379">"Refuser"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Remplacer <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuer en arrière-plan"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Fichiers récents sur le téléphone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fichiers sur le téléphone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> sur le téléphone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fichiers sur <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fichiers de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fichiers de <xliff:g id="LABEL">%1$s</xliff:g> (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Images récentes sur le téléphone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Images sur le téléphone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Images sur l\'appareil <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Images de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Images de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Images"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vidéos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nom du dossier"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nouveau nom"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Afficher un aperçu du fichier <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Parcourir les fichiers dans d\'autres applications"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonyme"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Autoriser l\'accès à « <xliff:g id="DIRECTORY">%1$s</xliff:g> »"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Cela permettra à « <xliff:g id="APPNAME">%1$s</xliff:g> » d\'accéder à tous les fichiers actuellement stockés sous ce lieu et à tout contenu stocké ici à l\'avenir."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Rechercher sur ce téléphone"</string>
 </resources>
diff --git a/res/values-fr/config.xml b/res/values-fr/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-fr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 73048ab..fc95c55 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Partager"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Supprimer"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Tout sélectionner"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Sélectionner"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Trier par"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copier vers…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Déplacer vers…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compresser"</string>
@@ -48,7 +50,7 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Copier"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Coller"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"Coller dans le dossier"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"Aff. mém. stock. interne"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Aff. mémoire stockage interne"</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"Masquer mém. stock. int."</string>
     <string name="button_select" msgid="240863497069321364">"Sélectionner"</string>
     <string name="button_copy" msgid="8219059853840996027">"Copier"</string>
@@ -65,16 +67,27 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Taille"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Dernière modif."</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nom de fichier (de A à Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (de A à Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Taille (plus petits d\'abord)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modifiés (plus anciens d\'abord)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nom de fichier (de Z à A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (de Z à A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Taille (plus grands d\'abord)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modifiés (plus récents d\'abord)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Trier par"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Triés par <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Nombre d\'éléments"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Croissant"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Décroissant"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Afficher les répertoires racines"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Masquer les répertoires racines"</string>
     <string name="save_error" msgid="8631128801982095782">"Échec de l\'enregistrement du document"</string>
     <string name="create_error" msgid="3092144450044861994">"Échec de la création du dossier"</string>
     <string name="query_error" msgid="6625421453613879336">"Impossible de charger le contenu pour le moment"</string>
     <string name="root_recent" msgid="1080156975424341623">"Récents"</string>
-    <string name="root_available_bytes" msgid="8269870862691408864">"Espace disponible : <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> disponible(s)"</string>
     <string name="root_type_service" msgid="6521366147466512289">"Services de stockage"</string>
     <string name="root_type_shortcut" msgid="6059343175525442279">"Raccourcis"</string>
     <string name="root_type_device" msgid="1713604128005476585">"Appareils"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> éléments…</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Annuler"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Préparation à la copie…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Préparation à la compression…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Préparation de l\'extraction…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Préparation au déplacement…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Préparation à la suppression…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Préparation..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Préparation..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Préparation..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Préparation..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Préparation..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> élément</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" sur <xliff:g id="STORAGE"><i>^3</i></xliff:g> ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à vos données, y compris les photos et les vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ne plus demander"</string>
     <string name="allow" msgid="1275746941353040309">"Autoriser"</string>
     <string name="deny" msgid="5127201668078153379">"Refuser"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Remplacer <xliff:g id="NAME">%1$s</xliff:g> ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuer en arrière-plan"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Fichiers récents sur le téléphone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fichiers sur le téléphone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> sur le téléphone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fichiers sur <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fichiers provenant de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fichiers provenant de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Images récentes sur le téléphone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Images sur le téléphone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Images sur <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Images sur <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Images sur <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Images"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vidéos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documents"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nom du dossier"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nouveau nom"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Prévisualiser le fichier <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Parcourir des fichiers dans d\'autres applications"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonyme"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Autoriser l\'accès à \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"L\'application <xliff:g id="APPNAME">%1$s</xliff:g> bénéficiera alors d\'un accès complet à l\'ensemble des fichiers actuellement stockés à cet emplacement et à l\'ensemble du contenu qui y sera stocké à l\'avenir."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Rechercher sur ce téléphone"</string>
 </resources>
diff --git a/res/values-gl/config.xml b/res/values-gl/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-gl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 606af08..45f2903 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Compartir"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Eliminar"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Seleccionar todo"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Seleccionar"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordenar por…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiar en…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Mover a…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamaño"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nome de ficheiro (A a Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (A a Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamaño (máis pequeno primeiro)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modificación (máis antigo primeiro)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nome de ficheiro (Z a A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (Z a A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamaño (máis grande primeiro)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modificación (máis recente primeiro)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordenar por"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Ordenado por <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Número de elementos"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Abre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raíces"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ocultar raíces"</string>
     <string name="save_error" msgid="8631128801982095782">"Non se puido gardar o documento"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Eliminando <xliff:g id="COUNT_0">%1$d</xliff:g> elemento.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Desfacer"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparando para copiar…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparándose para comprimir..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparándose para a extracción…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparándose para mover..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparando para eliminar…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparando…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparando…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparando…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparando…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparando…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Non se puideron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no almacenamento de <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> aos teus datos almacenados en <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incluídos vídeos e fotos?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Non preguntar de novo"</string>
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Denegar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arquivo<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Queres sobrescribir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuar coa operación en segundo plano"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">Seleccionáronse <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Seleccionouse <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Ficheiros recentes do teléfono"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Ficheiros do teléfono"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> no teléfono"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Ficheiros do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Ficheiros de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Ficheiros de <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imaxes recentes no teléfono"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imaxes no teléfono"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imaxes en <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imaxes de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imaxes de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imaxes"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documentos"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nome do cartafol"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nome novo"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Vista previa do ficheiro <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Consultar ficheiros noutras aplicacións"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Aplicación anónima"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permitir acceso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Queres permitir o acceso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" en \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Permitirá que \"<xliff:g id="APPNAME">%1$s</xliff:g>\" teña acceso completo a todos os ficheiros almacenados actualmente ou no futuro nesta localización."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Realiza buscas neste teléfono"</string>
 </resources>
diff --git a/res/values-gu/config.xml b/res/values-gu/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-gu/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index c2116c4..c5ea19c 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"શેર કરો"</string>
     <string name="menu_delete" msgid="1022254131543256626">"કાઢી નાખો"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"બધા પસંદ કરો"</string>
+    <string name="menu_select" msgid="1366061076507142387">"પસંદ કરો"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"આ મુજબ સૉર્ટ કરો..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"આના પર કૉપિ કરો…"</string>
     <string name="menu_move" msgid="2310760789561129882">"આમાં ખસેડો…"</string>
     <string name="menu_compress" msgid="37539111904724188">"સંકુચિત કરો"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"પ્રકાર"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"કદ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"સંશોધિત"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ફાઇલનું નામ (એ થી ઝેડ)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"પ્રકાર (એ થી ઝેડ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"કદ (સૌથી નાનું પહેલા)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ફેરફારનો દિન (જૂનાથી શરૂ)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ફાઇલનું નામ (ઝેડ થી એ)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"પ્રકાર (ઝેડ થી એ)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"કદ (સૌથી મોટું પહેલા)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ફેરફારનો દિન (નવાથી શરૂ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"આ મુજબ સૉર્ટ કરો"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> મુજબ સૉર્ટ કરેલ"</string>
     <string name="directory_items" msgid="6645621978998614003">"આઇટમની સંખ્યા:"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ચઢતાં ક્રમમાં"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ઉતરતા ક્રમમાં"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ખોલો"</string>
     <string name="drawer_open" msgid="8071673398187261741">"રૂટ્સ બતાવો"</string>
     <string name="drawer_close" msgid="4263880768630848848">"રૂટ્સ છુપાવો"</string>
     <string name="save_error" msgid="8631128801982095782">"દસ્તાવેજ સાચવવામાં નિષ્ફળ થયાં"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ કાઢી નાખી રહ્યા છીએ.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"પૂર્વવત્ કરો"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"કૉપિ કરવા માટે તૈયારી કરે છે…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"સંકુચિત કરવાની તૈયારી કરી રહ્યા છીએ…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"કાઢવાની તૈયારી કરી રહ્યાં છીએ…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ખસેડવા માટે તૈયાર કરી રહ્યું છે…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"કાઢી નાખવાની તૈયારી કરે છે…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"તૈયારી કરી રહ્યાં છીએ…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"તૈયારી કરી રહ્યાં છીએ…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"તૈયારી કરી રહ્યાં છીએ…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"તૈયારી કરી રહ્યાં છીએ…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"તૈયારી કરી રહ્યાં છીએ…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમની કૉપિ કરી ન શક્યા</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^3</i></xliff:g> પર <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટો અને વિડિઓઝ સહિત તમારા ડેટાની અ‍ૅક્સેસ આપીએ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ફરીથી પૂછશો નહીં"</string>
     <string name="allow" msgid="1275746941353040309">"મંજૂરી આપો"</string>
     <string name="deny" msgid="5127201668078153379">"નકારો"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"આર્કાઇવ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> અધિલેખિત કરીએ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"પૃષ્ઠભૂમિમાં ચાલુ રાખો"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ફોન પરની તાજેતરની ફાઇલો"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ફોન પરની ફાઇલો"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ફોન પર <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> પરની ફાઇલો"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>માંથી ફાઇલો"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>માંથી ફાઇલો"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ફોન પરની તાજેતરની છબીઓ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ફોન પરની છબીઓ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> પરની છબીઓ"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>ની છબીઓ"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>ની છબીઓ"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"છબીઓ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ઑડિયો"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"વીડિયો"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"દસ્તાવેજો"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ફોલ્ડરનું નામ"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"નવું નામ"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ફાઇલને પ્રીવ્યૂ કરો"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"અન્ય ઍપમાં ફાઇલો બ્રાઉઝ કરો"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"અજ્ઞાત"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"ને ઍક્સેસની મંજૂરી આપો"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" પર \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"ના ઍક્સેસને મંજૂરી આપીએ?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"આ \"<xliff:g id="APPNAME">%1$s</xliff:g>\"ને હાલ આ સ્થાન હેઠળ સ્ટોર કરેલી બધી ફાઇલો અને ભવિષ્યમાં અહીં સ્ટોર કરાતા કોઈપણ કન્ટેન્ટના સંપૂર્ણ ઍક્સેસની મંજૂરી આપશે."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"આ ફોન શોધો"</string>
 </resources>
diff --git a/res/values-hi/config.xml b/res/values-hi/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-hi/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-hi/mimes.xml b/res/values-hi/mimes.xml
index ffff6e9..f5a78ae 100644
--- a/res/values-hi/mimes.xml
+++ b/res/values-hi/mimes.xml
@@ -39,7 +39,7 @@
     <string name="gdraw_file_type" msgid="655688091676820371">"Google आरेखण"</string>
     <string name="gtable_file_type" msgid="7332773878374650335">"Google टेबल"</string>
     <string name="gform_file_type" msgid="4803176103746107611">"Google फ़ॉर्म"</string>
-    <string name="gmap_file_type" msgid="6684180781808007016">"Google मानचित्र"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google मैप"</string>
     <string name="gsite_file_type" msgid="3742812051249149526">"Google साइट"</string>
     <string name="directory_type" msgid="2702987727566226354">"फ़ोल्डर"</string>
 </resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 3ab5f55..625a98e 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -27,7 +27,7 @@
     <string name="menu_create_dir" msgid="2413624798689091042">"नया फ़ोल्डर"</string>
     <string name="menu_grid" msgid="1453636521731880680">"ग्रिड दृश्य"</string>
     <string name="menu_list" msgid="6714267452146410402">"सूची दृश्य"</string>
-    <string name="menu_search" msgid="1876699106790719849">"सर्च करें"</string>
+    <string name="menu_search" msgid="1876699106790719849">"खोजें"</string>
     <string name="menu_settings" msgid="6520844520117939047">"जगह सेटिंग"</string>
     <string name="menu_open" msgid="9092138100049759315">"खोलें"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"इसमें खोलें"</string>
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"शेयर करें"</string>
     <string name="menu_delete" msgid="1022254131543256626">"मिटाएं"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"सभी चुनें"</string>
+    <string name="menu_select" msgid="1366061076507142387">"चुनें"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"इस क्रम में लगाएं..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"इनकी कॉपी करें..."</string>
     <string name="menu_move" msgid="2310760789561129882">"यहां ले जाएं…"</string>
     <string name="menu_compress" msgid="37539111904724188">"कंप्रेस करें"</string>
@@ -64,10 +66,21 @@
     <string name="sort_dimension_summary" msgid="7724534446881397860">"सारांश"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string>
-    <string name="sort_dimension_date" msgid="4231005651895254033">"बदलनेे का समय"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"बदले जाने का समय"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"फ़ाइल का नाम (A से Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"प्रकार (A से Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"आकार (सबसे छोटा पहले)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"बदला गया (पुरानी तारीख से)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"फ़ाइल का नाम (Z से A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"प्रकार (Z से A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"आकार (सबसे बड़ा पहले)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"बदला गया (नई तारीख से)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"इस क्रम से लगाएं"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> से क्रम से लगाया गया"</string>
     <string name="directory_items" msgid="6645621978998614003">"आइटम की संख्या"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"बढ़ते क्रम में"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"घटते क्रम में"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> खोलें"</string>
     <string name="drawer_open" msgid="8071673398187261741">"रूट दिखाएं"</string>
     <string name="drawer_close" msgid="4263880768630848848">"रूट छिपाएं"</string>
     <string name="save_error" msgid="8631128801982095782">"दस्तावेज़ सहेजने में विफल रहा"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम मिटाए जा रहे हैं.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"पूर्ववत करें"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"कॉपी करने की तैयारी हो रही है…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"कंप्रेस की तैयार हो रही है..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"निकालने की तैयारी हो रही है…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ले जाने की तैयारी हो रही है…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"हटाने के लिए तैयार हो रहा है…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"तैयार किया जा रहा है..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"तैयार किया जा रहा है..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"तैयार किया जा रहा है..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"तैयार किया जा रहा है..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"तैयार किया जा रहा है..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम कॉपी नहीं किए जा सके</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> डिक्शनरी तक पहुंचने देना चाहते हैं?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> डिक्शनरी तक पहुंचने देना चाहते हैं?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो के साथ, अपने डेटा तक पहुंचने देना चाहते हैं?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"फिर से ना पूछें"</string>
     <string name="allow" msgid="1275746941353040309">"अनुमति दें"</string>
     <string name="deny" msgid="5127201668078153379">"अस्वीकार करें"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"संग्रह<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> को ओवरराइट करना चाहते हैं?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"बैकग्राउंड में जारी रखें"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> चुना गया</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चुने गए</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"फ़ोन पर मौजूद हाल ही की फ़ाइलें"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"फ़ोन पर फ़ाइलें"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"फ़ोन पर <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> पर फ़ाइलें"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> की फ़ाइलें"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> की फ़ाइलें"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"फ़ोन पर मौजूद हाल ही की इमेज"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"फ़ोन पर मौजूद इमेज"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> पर मौजूद इमेज"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> की इमेज"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> की इमेज"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"इमेज"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ऑडियो"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"वीडियो"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"दस्तावेज़"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"फ़ोल्डर का नाम"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"नया नाम"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> फ़ाइल की झलक देखें"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"दूसरे ऐप्लिकेशन में फ़ाइलें ब्राउज़ करें"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"अनाम"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" एक्सेस करने दें"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" पर \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" का एक्सेस दें?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"यह \"<xliff:g id="APPNAME">%1$s</xliff:g>\" को इस जगह में इस समय सेव की गई सभी फ़ाइलों और आने वाले समय में यहां सेव की जाने वाली किसी भी सामग्री का पूरा एक्सेस करने देगा."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"यह फ़ोन खोजें"</string>
 </resources>
diff --git a/res/values-hr/config.xml b/res/values-hr/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-hr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index b5315d2..5abece4 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Dijeli"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Izbriši"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Odaberi sve"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Odabir"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Kriterij razvrstavanja..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiraj u…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Premjesti u…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Sažmi"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Vrsta"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veličina"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmijenjeno"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Naziv datoteke (A – Ž)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Vrsta (A – Ž)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Veličina (od najmanjeg)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Izmjena (od najstarijeg)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Naziv datoteke (Ž – A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Vrsta (Ž – A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Veličina (od najvećeg)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Izmjena (od najnovijeg)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Kriterij razvrstavanja"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Poredano po: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Broj stavki"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Uzlazno"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Silazno"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Otvorite aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Prikaži korijene"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Sakrij korijene"</string>
     <string name="save_error" msgid="8631128801982095782">"Nije uspjelo spremanje dokumenta"</string>
@@ -117,11 +130,11 @@
       <item quantity="other">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> stavki.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Poništi"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Priprema za kopiranje…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Priprema za sažimanje…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Priprema za izdvajanje…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Priprema za premještanje…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Priprema za brisanje…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Pripremanje..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Pripremanje..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Pripremanje..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Pripremanje..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Pripremanje..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> stavke nije uspjelo</item>
@@ -188,7 +201,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na vanjskoj pohrani (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dopustiti pristup podacima, uključujući fotografije i videozapise na vanjskoj pohrani (<xliff:g id="STORAGE"><i>^2</i></xliff:g>)?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Više me ne pitaj"</string>
     <string name="allow" msgid="1275746941353040309">"Dopusti"</string>
     <string name="deny" msgid="5127201668078153379">"Odbij"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -227,4 +239,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhiva<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Prebrisati <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Nastavi u pozadini"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> odabrana stavka</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> odabrane stavke</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> odabranih stavki</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nedavne datoteke na telefonu"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Datoteke na telefonu"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> na telefonu"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Datoteke na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Datoteke s usluge <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Datoteke s usluge <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nedavne slike na telefonu"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Slike na telefonu"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Slike na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Slike s usluge <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Slike s usluge <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Slike"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Zvuk"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videozapisi"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Naziv mape"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novi naziv"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Pregledajte datoteku <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Pregledajte datoteke u drugim aplikacijama"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonimno"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Dopusti pristup direktoriju \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Želite li dopustiti pristup direktoriju \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" na uređaju \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Aplikaciji \"<xliff:g id="APPNAME">%1$s</xliff:g>\" omogućit će potpuni pristup svim datotekama koje su trenutačno pohranjene na toj lokaciji i tu će se spremati sav budući sadržaj."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Pretražite ovaj telefon"</string>
 </resources>
diff --git a/res/values-hu/config.xml b/res/values-hu/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-hu/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index ed24c97..00d1c0d 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Megosztás"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Törlés"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Az összes kijelölése"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Kiválasztás"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Rendezési szempont"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Másolás ide…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Áthelyezés…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Tömörítés"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Típus"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Méret"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Módosítva"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Fájlnév (növekvő)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Típus (növekvő)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Méret (legkisebbtől)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Módosítva (régebbi elöl)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Fájlnév (csökkenő)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Típus (csökkenő)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Méret (legnagyobbtól)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Módosítva (újabb elöl)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Rendezési szempont"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Rendezés <xliff:g id="LABEL">%s</xliff:g> szerint"</string>
     <string name="directory_items" msgid="6645621978998614003">"Elemek száma"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Növekvő"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Csökkenő"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> megnyitása"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Gyökérszint megjelenítése"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Gyökérszint elrejtése"</string>
     <string name="save_error" msgid="8631128801982095782">"Nem sikerült menteni a dokumentumot"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elem törlése folyamatban.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Visszavonás"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Felkészülés a másolásra…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Felkészülés a tömörítésre…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Kicsomagolás előkészítése…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Áthelyezés előkészítése…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Törlés előkészítése…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Előkészítés…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Előkészítés…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Előkészítés…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Előkészítés…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Előkészítés…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="TOTALCOUNT">%2$d</xliff:g>/<xliff:g id="COUNT_0">%1$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elem másolása sikertelen</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz itt: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> alkalmazásnak a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Hozzáférést biztosít a(z) <xliff:g id="STORAGE"><i>^2</i></xliff:g> tárhelyen található adataihoz a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára, beleértve a képeket és videókat is?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ne jelenjen meg többé"</string>
     <string name="allow" msgid="1275746941353040309">"Engedélyezés"</string>
     <string name="deny" msgid="5127201668078153379">"Elutasítás"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Felülírja a következő fájlt: <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Folytatás a háttérben"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kiválasztva</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kiválasztva</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Legutóbbi fájlok a telefonon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fájlok a telefonon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> a telefonon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fájlok a(z) <xliff:g id="DEVICE">%1$s</xliff:g> eszközön"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fájlok innen: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fájlok innen: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"A telefonon lévő friss képek"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"A telefonon lévő képek"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"A(z) <xliff:g id="DEVICE">%1$s</xliff:g> eszközön lévő képek"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Képek innen: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Képek innen: <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Képek"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Hangok"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videók"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumentumok"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Mappa neve"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Új név"</string>
+    <string name="preview_file" msgid="4056622696305432343">"A(z) <xliff:g id="FILENAME">%1$s</xliff:g> előnézete"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Fájlok böngészése más alkalmazásokban"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Névtelen"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Hozzáférés engedélyezése a következőhöz: „<xliff:g id="DIRECTORY">%1$s</xliff:g>”"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Engedélyezi a(z) „<xliff:g id="DIRECTORY">%1$s</xliff:g>” könyvtárhoz való hozzáférést itt: „<xliff:g id="ROOT">%2$s</xliff:g>”?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Engedélyezi a teljes hozzáférést a(z) „<xliff:g id="APPNAME">%1$s</xliff:g>” alkalmazás számára a jelenleg és a jövőben ezen a helyen tárolt tartalmakhoz."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Keresés ezen a telefonon"</string>
 </resources>
diff --git a/res/values-hy/config.xml b/res/values-hy/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-hy/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 8d036a7..8b77191 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Կիսվել"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Ջնջել"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Ընտրել բոլորը"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Ընտրել"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Տեսակավորել ըստ…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Պատճենել…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Տեղափոխել…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Սեղմել"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Տեսակը"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Չափը"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Փոփոխվել է"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ֆայլի անվան (Ա – Ֆ)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"տեսակի (Ա – Ֆ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"չափի (սկզբում փոքրերը)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"փոփոխման (հնից նոր)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ֆայլի անվան (Ֆ – Ա)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"տեսակի (Ֆ – Ա)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"չափի (սկզբում մեծերը)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"փոփոխման (նորից հին)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Տեսակավորում"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Տեսակավորված ըստ՝ <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Տարրերի քանակ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Աճման կարգով"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Նվազման կարգով"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Բացել <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Ցույց տալ արմատները"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Թաքցնել արմատները"</string>
     <string name="save_error" msgid="8631128801982095782">"Չհաջողվեց պահել փաստաթուղթը"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> տարրի ջնջում:</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Հետարկել"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Պատճենման նախապատրաստում…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Սեղմելու նախապատրաստում…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Պատրաստվում է արտահանել…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Տեղափոխման նախապատրաստում…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Պատրաստվում է ջնջել…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Նախապատրաստում..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Նախապատրաստում..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Նախապատրաստում..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Նախապատրաստում..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Նախապատրաստում..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
@@ -161,7 +174,7 @@
       <item quantity="other">Այս ֆայլը փոխարկվել են այլ ձևաչափի՝ <xliff:g id="LIST_1">%1$s</xliff:g></item>
     </plurals>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
-      <item quantity="one">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> items to clipboard.</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> տարր պատճենվեց սեղմատախտակին։</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> տարր պատճենվեց սեղմատախտակին:</item>
     </plurals>
     <string name="file_operation_rejected" msgid="4301554203329008794">"Ֆայլի աշխատանքը չի աջակցվում:"</string>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ի <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ում պահվող ձեր տվյալները, այդ թվում նաև լուսանկարները և տեսանյութերը, օգտագործելու թույլտվություն:"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Այլևս չհարցնել"</string>
     <string name="allow" msgid="1275746941353040309">"Թույլատրել"</string>
     <string name="deny" msgid="5127201668078153379">"Մերժել"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Փոխարինե՞լ <xliff:g id="NAME">%1$s</xliff:g> ֆայլը։"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Շարունակել ֆոնում"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Ձեր հեռախոսում վերջերս բացված ֆայլերը"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Ֆայլեր հեռախոսում"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> հեռախոսում"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Ֆայլեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքում"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Ֆայլեր <xliff:g id="LABEL">%1$s</xliff:g> ծառայությունից"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Ֆայլեր <xliff:g id="LABEL">%1$s</xliff:g> (<xliff:g id="SUMMARY">%2$s</xliff:g>) ծառայությունից"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Նոր պատկերներ հեռախոսում"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Պատկերներ հեռախոսում"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Պատկերներ <xliff:g id="DEVICE">%1$s</xliff:g> սարքում"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Պատկերների սկզբնաղբյուր՝ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Պատկերների սկզբնաղբյուր՝ <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Պատկերներ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Աուդիո"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Տեսանյութեր"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Փաստաթղթեր"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Պանակի անունը"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Նոր անունը"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Դիտել «<xliff:g id="FILENAME">%1$s</xliff:g>» ֆայլը"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Գտնել ֆայլեր այլ հավելվածներում"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Անանուն"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Հասանելի դարձնել <xliff:g id="DIRECTORY">%1$s</xliff:g> պանակը"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածին հասանելի կլինեն բոլոր ֆայլերը, որոնք այժմ պահվում են այս պանակում կամ կտեղափոխվեն այստեղ հետագայում:"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Որոնեք հեռախոսում"</string>
 </resources>
diff --git a/res/values-in/config.xml b/res/values-in/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-in/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 8ef3466..64ba8c6 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Bagikan"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Hapus"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Pilih semua"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Pilih"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Urutkan menurut..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Salin ke…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Pindahkan ke..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Kompresi"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Jenis"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Ukuran"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Diubah"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nama file (A ke Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Jenis (A ke Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Ukuran (terkecil dulu)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Diubah (terlama dulu)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nama file (Z ke A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Jenis (Z ke A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Ukuran (terbesar dulu)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Diubah (terbaru dulu)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Urutkan menurut"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Diurutkan menurut <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Jumlah item"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Naik"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Turun"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Tampilkan root"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Sembunyikan root"</string>
     <string name="save_error" msgid="8631128801982095782">"Gagal menyimpan dokumen"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Menghapus <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Urungkan"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Bersiap untuk menyalin…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Bersiap untuk mengompres..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Bersiap mengekstrak…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Bersiap memindahkan…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Bersiap menghapus…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Menyiapkan..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Menyiapkan..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Menyiapkan..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Menyiapkan..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Menyiapkan..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
@@ -134,7 +147,7 @@
       <item quantity="other">Tidak dapat menghapus <xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
       <item quantity="one">Tidak dapat menghapus <xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="2385563502445129570">"Ketuk untuk melihat detail"</string>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"Tap untuk melihat detail"</string>
     <string name="close" msgid="905969391788869975">"Tutup"</string>
     <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
       <item quantity="other">File ini tidak disalin: <xliff:g id="LIST_1">%1$s</xliff:g></item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke data Anda, termasuk foto dan video, di <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Jangan tanya lagi"</string>
     <string name="allow" msgid="1275746941353040309">"Izinkan"</string>
     <string name="deny" msgid="5127201668078153379">"Tolak"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arsip<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Timpa <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Lanjutkan di background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"File terbaru di ponsel"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"File di ponsel"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> di ponsel"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"File di <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"File dari <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"File dari <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Gambar terkini di ponsel"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Gambar di ponsel"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Gambar di <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Gambar dari <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Gambar dari <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Gambar"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumen"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nama folder"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nama baru"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Pratinjau file <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Cari file di aplikasi lain"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonim"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Izinkan akses ke \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Izinkan akses ke \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" di \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Ini akan mengizinkan \"<xliff:g id="APPNAME">%1$s</xliff:g>\" untuk memiliki akses penuh ke semua file yang saat ini tersimpan di lokasi ini, dan semua konten yang nantinya disimpan di sini."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Telusuri ponsel ini"</string>
 </resources>
diff --git a/res/values-is/config.xml b/res/values-is/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-is/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index b5be412..09d5366 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Deila"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Eyða"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Velja allt"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Velja"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Raða eftir..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Afrita í…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Færa í…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Þjappa"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Gerð"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Stærð"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Breytt"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Skráarheiti (A til Ö)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Gerð (A til Ö)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Stærð (minnsta fyrst)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Breytt (elsta fyrst)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Skráarheiti (Ö til A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Gerð (Ö til A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Stærð (stærsta fyrst)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Breytt (nýjasta fyrst)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Raða eftir"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Raðað eftir <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Fjöldi atriða"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Hækkandi"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Lækkandi"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Opna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Sýna rótarsöfn"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Fela rótarsöfn"</string>
     <string name="save_error" msgid="8631128801982095782">"Ekki tókst að vista skjalið"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Eyðir <xliff:g id="COUNT_1">%1$d</xliff:g> atriðum.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Afturkalla"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Undirbúningur fyrir afritun…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Undirbýr þjöppun…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Undirbýr að draga út…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Flutningur undirbúinn…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Býr sig undir að eyða…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Undirbýr..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Undirbýr..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Undirbýr..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Undirbýr..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Undirbýr..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Gat ekki afritað <xliff:g id="COUNT_1">%1$d</xliff:g> atriði</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Viltu veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> á <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Viltu veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Viltu veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að gögnunum þínum, þar á meðal myndum og myndskeiðum, á <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ekki spyrja aftur"</string>
     <string name="allow" msgid="1275746941353040309">"Leyfa"</string>
     <string name="deny" msgid="5127201668078153379">"Hafna"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"geymsla<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Skrifa yfir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Halda áfram í bakgrunni"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> valið</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valin</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nýlegar skrár í síma"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Skrár í síma"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> í símanum"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Skrár í <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Skrár frá <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Skrár frá <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nýlegar myndir í síma"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Myndir í síma"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Myndir í <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Myndir frá <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Myndir frá <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Myndir"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Hljóð"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeó"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Skjöl"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Möppuheiti"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nýtt heiti"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Forskoða skrána <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Skoða skrár í öðrum forritum"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Nafnlaus"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Leyfa aðgang að „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Leyfa aðgang að „<xliff:g id="DIRECTORY">%1$s</xliff:g>“ á „<xliff:g id="ROOT">%2$s</xliff:g>“?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Þetta gefur „<xliff:g id="APPNAME">%1$s</xliff:g>“ fullan aðgang að öllum skrám sem eru geymdar á þessum stað eins og er og öllu efni sem verður geymt hér síðar meir."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Leita í þessum síma"</string>
 </resources>
diff --git a/res/values-it/config.xml b/res/values-it/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-it/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index fcf7baa..4a050ed 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Condividi"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Elimina"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Seleziona tutto"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Seleziona"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordina per…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copia in…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Sposta in…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimi"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Dimensioni"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ultima modifica"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nome file (da A a Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (dalla A alla Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Dimensione (crescente)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modifica meno recente"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nome file (da Z a A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (da Z a A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Dimensione (decrescente)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modifica più recente"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordina per"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Ordine per <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Numero di elementi"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Crescente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Decrescente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Apri <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostra nodi principali"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Nascondi nodi principali"</string>
     <string name="save_error" msgid="8631128801982095782">"Impossibile salvare il documento."</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Eliminazione di <xliff:g id="COUNT_0">%1$d</xliff:g> elemento.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Annulla"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparazione alla copia…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparazione alla compressione…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparazione all\'estrazione…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparazione dello spostamento…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparazione eliminazione…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparazione…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparazione…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparazione…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparazione…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparazione…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Copia di <xliff:g id="COUNT_1">%1$d</xliff:g> elementi non riuscita</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> su <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso ai tuoi dati, inclusi video e foto, sull\'unità <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Non chiedermelo più"</string>
     <string name="allow" msgid="1275746941353040309">"Consenti"</string>
     <string name="deny" msgid="5127201668078153379">"Nega"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archivio<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Sovrascrivere <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continua in background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi selezionati</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento selezionato</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"File recenti sul telefono"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"File sul telefono"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> sul telefono"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"File su <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"File di <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"File di <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Immagini recenti sul telefono"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Immagini sul telefono"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Immagini su <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Immagini di <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Immagini di <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Immagini"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nome cartella"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nuovo nome"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Visualizza il file <xliff:g id="FILENAME">%1$s</xliff:g> in anteprima"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Sfoglia i file in altre app"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonima"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Consenti l\'accesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Vuoi consentire l\'accesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" su \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" potrà avere accesso completo a tutti i file attualmente memorizzati in questa posizione e ai contenuti salvati in futuro qui."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Cerca su questo telefono"</string>
 </resources>
diff --git a/res/values-iw/config.xml b/res/values-iw/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-iw/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 7a45d7f..5a28897 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"שתף"</string>
     <string name="menu_delete" msgid="1022254131543256626">"מחיקה"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"בחר הכל"</string>
+    <string name="menu_select" msgid="1366061076507142387">"בחירה"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"מיון לפי…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"העתק אל…"</string>
     <string name="menu_move" msgid="2310760789561129882">"העבר אל…"</string>
     <string name="menu_compress" msgid="37539111904724188">"דחוס"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"סוג"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"גודל"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"שינוי אחרון"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"שם הקובץ (א\' עד ת\')"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"סוג (א\' עד ת\')"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"גודל (מהקטן לגדול)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"השתנה (מהישן לחדש)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"שם הקובץ (ת\' עד א\')"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"סוג (ת\' עד א\')"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"גודל (מהגדול לקטן)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"השתנה (מהחדש לישן)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"מיון לפי"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"מיון לפי <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"מספר הפריטים"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"סדר עולה"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"סדר יורד"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"פתיחה של <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"הצג שורשים"</string>
     <string name="drawer_close" msgid="4263880768630848848">"הסתר שורשים"</string>
     <string name="save_error" msgid="8631128801982095782">"שמירת המסמך נכשלה"</string>
@@ -122,11 +135,11 @@
       <item quantity="one">מוחק פריט <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"ביטול"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"מתכונן להעתקה..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"מתכונן לדחיסה..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"מתכונן לשליפה…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"מתכונן להעברה…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"מתכונן למחיקה…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"בהכנה…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"בהכנה…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"בהכנה…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"בהכנה…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"בהכנה…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="two">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
@@ -204,9 +217,8 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לספריה <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> באחסון <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה אל ספריית <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לנתונים שלך, כולל תמונות וסרטונים, השמורים ב<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ראיתי פעם אחת, זה מספיק"</string>
     <string name="allow" msgid="1275746941353040309">"כן, זה בסדר"</string>
-    <string name="deny" msgid="5127201668078153379">"לא, אין מצב"</string>
+    <string name="deny" msgid="5127201668078153379">"לא, תודה"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
       <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item>
       <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item>
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"להחליף את <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"המשך ברקע"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="two">נבחרו <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+      <item quantity="many">נבחרו <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+      <item quantity="other">נבחרו <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+      <item quantity="one">נבחר פריט אחד (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"קבצים אחרונים בטלפון"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"קבצים בטלפון"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> בטלפון"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"קבצים ב-<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"קבצים מ-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"קבצים מ-<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"תמונות אחרונות בטלפון"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"תמונות בטלפון"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"התמונות ב-<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"תמונות מ-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"תמונו מ-<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"תמונות"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"אודיו"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"סרטונים"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"מסמכים"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"שם תיקייה"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"שם חדש"</string>
+    <string name="preview_file" msgid="4056622696305432343">"תצוגה מקדימה של הקובץ <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"חיפוש קבצים באפליקציות אחרות"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"אנונימית"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"מתן גישה אל \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"לאפשר גישה אל \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ב-\"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"לאפליקציה \"<xliff:g id="APPNAME">%1$s</xliff:g>\" תהיה הרשאת גישה מלאה לכל הקבצים שמאוחסנים כרגע במיקום זה, ולכל תוכן שיאוחסן כאן בעתיד."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"חיפוש בטלפון זה"</string>
 </resources>
diff --git a/res/values-ja/config.xml b/res/values-ja/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ja/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index c06bf9b..edde9f1 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"共有"</string>
     <string name="menu_delete" msgid="1022254131543256626">"削除"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"すべて選択"</string>
+    <string name="menu_select" msgid="1366061076507142387">"選択"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"並べ替え..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"コピー…"</string>
     <string name="menu_move" msgid="2310760789561129882">"移動…"</string>
     <string name="menu_compress" msgid="37539111904724188">"圧縮"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"タイプ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"サイズ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"最終変更"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ファイル名(昇順)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"形式(昇順)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"サイズ(小さい順)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"変更日(古い順)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ファイル名(降順)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"形式(降順)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"サイズ(大きい順)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"変更日(新しい順)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"並べ替え"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g>で並べ替え"</string>
     <string name="directory_items" msgid="6645621978998614003">"アイテム数"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"昇順"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"降順"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g>を開く"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ルートを表示する"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ルートを非表示にする"</string>
     <string name="save_error" msgid="8631128801982095782">"ドキュメントを保存できませんでした"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 件のアイテムを削除しています。</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"元に戻す"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"コピーの準備をしています…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"圧縮の準備をしています…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"解凍を準備しています…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"移動の準備をしています…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"削除の準備をしています…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"準備しています…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"準備しています…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"準備しています…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"準備しています…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"準備しています…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 件のアイテムをコピーできませんでした</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>アプリに <xliff:g id="STORAGE"><i>^3</i></xliff:g>の <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ディレクトリへのアクセスを許可しますか?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>アプリに <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ディレクトリへのアクセスを許可しますか?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>の写真や動画などのデータへのアクセスを<xliff:g id="APPNAME"><b>^1</b></xliff:g>アプリに許可しますか?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"今後表示しない"</string>
     <string name="allow" msgid="1275746941353040309">"許可"</string>
     <string name="deny" msgid="5127201668078153379">"許可しない"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> を上書きしますか?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"バックグラウンドで続行"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個を選択中</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個を選択中</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"スマートフォンで最近使用したファイル"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"スマートフォンにあるファイル"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"スマートフォンにある<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> にあるファイル"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>のファイル"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> のファイル"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"スマートフォンに最近保存された画像"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"スマートフォンに保存されている画像"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> に保存されている画像"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> の画像"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>(<xliff:g id="SUMMARY">%2$s</xliff:g>)の画像"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"画像"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"音声"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"動画"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ドキュメント"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"フォルダ名"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"新しい名前"</string>
+    <string name="preview_file" msgid="4056622696305432343">"ファイル <xliff:g id="FILENAME">%1$s</xliff:g> をプレビューする"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"他のアプリでのファイル参照"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"匿名"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"「<xliff:g id="DIRECTORY">%1$s</xliff:g>」へのアクセスを許可"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"「<xliff:g id="ROOT">%2$s</xliff:g>」の「<xliff:g id="DIRECTORY">%1$s</xliff:g>」へのアクセスを許可しますか?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"現在この場所に保存されているすべてのファイル、および今後ここに保存されるすべてのコンテンツへのフルアクセスを「<xliff:g id="APPNAME">%1$s</xliff:g>」に許可します。"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"このスマートフォンを検索する"</string>
 </resources>
diff --git a/res/values-ka/config.xml b/res/values-ka/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ka/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 4868fc5..3349f73 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"გაზიარება"</string>
     <string name="menu_delete" msgid="1022254131543256626">"წაშლა"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"ყველას არჩევა"</string>
+    <string name="menu_select" msgid="1366061076507142387">"არჩევა"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"დალაგება კრიტერიუმით..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"კოპირება…"</string>
     <string name="menu_move" msgid="2310760789561129882">"გადაადგილება..."</string>
     <string name="menu_compress" msgid="37539111904724188">"შეკუმშვა"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ტიპი"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ზომა"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ცვლილება"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ფაილის სახელი (ა-ჰ)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ტიპი (ა-ჰ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ზომა (ჯერ უმცირესი)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ცვლილება (ჯერ უძველესი)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ფაილის სახელი (ჰ-ა)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ტიპი (ჰ-ა)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ზომა (ჯერ უდიდესი)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ცვლილება (ჯერ უახლესი)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"დალაგება კრიტერიუმით:"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"დალ. კრიტერიუმი: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"ერთეულების რაოდენობა"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ზრდადი"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"კლებადი"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g>-ის გახსნა"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ფესვების ჩვენება"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ფესვების დამალვა"</string>
     <string name="save_error" msgid="8631128801982095782">"დოკუმენტის შენახვა ვერ მოხერხდა"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">მიმდინარეობს <xliff:g id="COUNT_0">%1$d</xliff:g> ერთეულის წაშლა.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"მოქმედების გაუქმება"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"მზადდება კოპირებისთვის…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"მზადდება შესაკუმშად…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"მზადდება ამოღებისთვის…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"მზადდება გადაადგილებისთვის..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"მზადდება წასაშლელად…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"მზადდება..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"მზადდება..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"მზადდება..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"მზადდება..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"მზადდება..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>-დან"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ერთეული ვერ დაკოპირდა</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ის დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ზე არსებულ მონაცემებზე, მათ შორის, ფოტოებსა და ვიდეოებზე, წვდომის უფლებით?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"აღარ მკითხოთ"</string>
     <string name="allow" msgid="1275746941353040309">"დაშვება"</string>
     <string name="deny" msgid="5127201668078153379">"უარყოფა"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"არქივი<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"გსურთ <xliff:g id="NAME">%1$s</xliff:g>-ზე გადაწერა?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ფონურ რეჟიმში გაგრძელება"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">არჩეულია <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">არჩეულია <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ბოლოდროინდელი ფაილები ტელეფონზე"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ფაილები ტელეფონზე"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> ტელეფონზე"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"ფაილები <xliff:g id="DEVICE">%1$s</xliff:g>-ზე"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"ფაილები <xliff:g id="LABEL">%1$s</xliff:g>-იდან"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"ფაილები <xliff:g id="LABEL">%1$s</xliff:g>-იდან / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ბოლოდროინდელი სურათები ტელეფონზე"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"სურათები ტელეფონზე"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"სურათები <xliff:g id="DEVICE">%1$s</xliff:g>-ზე"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"სურათები <xliff:g id="LABEL">%1$s</xliff:g>-დან"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"სურათები <xliff:g id="LABEL">%1$s</xliff:g>-დან / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"სურათები"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"აუდიო"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ვიდეოები"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"დოკუმენტები"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"საქაღალდის სახელი"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ახალი სახელი"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ფაილის გადახედვა"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ფაილების დათვალიერება სხვა აპებში"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ანონიმური"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"„<xliff:g id="DIRECTORY">%1$s</xliff:g>“-ზე წვდომის დაშვება"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"გსურთ, დაუშვათ წვდომა „<xliff:g id="DIRECTORY">%1$s</xliff:g>“-ზე „<xliff:g id="ROOT">%2$s</xliff:g>“-იდან?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ეს ქმედება მიანიჭებს „<xliff:g id="APPNAME">%1$s</xliff:g>“-ს სრულ წვდომას ყველა ფაილზე, რომელიც ამჟამად ინახება ამ მდებარეობაზე და რომელიც მომავალში შეინახება."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ამ ტელეფონში ძიება"</string>
 </resources>
diff --git a/res/values-kk/config.xml b/res/values-kk/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-kk/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 00a6a72..ca05e98 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Бөлісу"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Жою"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Барлығын таңдау"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Таңдау"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Сұрыптау шарты..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Көшіру орны…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Тасымалдау…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Сығу"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tүрі"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Көлемі"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Өзгертілген уақыты"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Файл атауы (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Түрі (A–Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Өлшемі (ең кішісінен бастап)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Өзгертілген (ең ескісінен бастап)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Файл атауы (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Түрі (Z–A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Өлшемі (ең үлкенінен бастап)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Өзгертілген (ең жаңасынан бастап)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Реттеу шарты"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> бойынша реттелген"</string>
     <string name="directory_items" msgid="6645621978998614003">"Элементтер саны"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Арту ретімен"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Кему ретімен"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасын ашу"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Түбір қалтаны көрсету"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Түбір қалтаны жасыру"</string>
     <string name="save_error" msgid="8631128801982095782">"Құжат сақталмады"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жойылуда.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Қайтару"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Көшіруге дайындау…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Сығуға дайындалуда…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Шығарып алуға дайындалуда…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Тасымалдауға дайындау..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Жоюға дайындалуда…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Дайындалуда…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Дайындалуда…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Дайындалуда…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Дайындалуда…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Дайындалуда…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көшірілмеді</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="STORAGE"><i>^3</i></xliff:g> жадындағы <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына кіру рұқсаты берілсін бе?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына кіру рұқсаты берілсін бе?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="STORAGE"><i>^2</i></xliff:g> жадындағы деректерге, соның ішінде фотосуреттерге және бейнелерге кіру рұқсаты берілсін бе?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Қайта сұралмасын"</string>
     <string name="allow" msgid="1275746941353040309">"Рұқсат беру"</string>
     <string name="deny" msgid="5127201668078153379">"Бас тарту"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> қайта жазылсын ба?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Фонда жалғастыру"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> таңдалды</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> таңдалды</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Телефондағы соңғы файлдар"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Телефондағы файлдар"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Телефондағы <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысындағы файлдар"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> файлдары"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g> файлдары"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Телефондағы соңғы кескіндер"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Телефондағы кескіндер"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысындағы кескіндер"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> ұсынған кескіндер"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> жіберген кескіндер"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Кескіндер"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Aудиомазмұн"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Бейнелер"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Құжаттар"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Қалта атауы"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Жаңа атауы"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> файлын алдын ала қарау"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Басқа қолданбалардағы файлдарды шолу"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Анонимді"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" каталогін пайдалануға рұқсат ету"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Осы арқылы \"<xliff:g id="APPNAME">%1$s</xliff:g>\" қолданбасы қазір осы орында сақталған барлық файлды және болашақта қосылатын кез келген мазмұнды толықтай пайдалана алатын болады."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Осы телефонды іздеу"</string>
 </resources>
diff --git a/res/values-km/config.xml b/res/values-km/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-km/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 137b870..e782cc1 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"ចែករំលែក​"</string>
     <string name="menu_delete" msgid="1022254131543256626">"លុប"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"ជ្រើស​ទាំងអស់"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ជ្រើសរើស"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"តម្រៀប​តាម..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"ចម្លងទៅ…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ផ្លាស់ទីទៅ…"</string>
     <string name="menu_compress" msgid="37539111904724188">"បង្ហាប់"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ប្រភេទ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ទំហំ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"បានកែសម្រួល"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ឈ្មោះឯកសារ (A ដល់ Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ប្រភេទ (A ដល់ Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ទំហំ (តូចបំផុតមុនគេ)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"បានកែប្រែ (ចាស់បំផុតមុនគេ)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ឈ្មោះឯកសារ (Z ដល់ A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ប្រភេទ (Z ដល់ A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ទំហំ (ធំបំផុតមុនគេ)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"បានកែប្រែ (ថ្មីបំផុតមុនគេ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"តម្រៀបតាម"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"តម្រៀបតាម <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"ចំនួន​ធាតុ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ឡើង"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ចុះ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"បើក <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"បង្ហាញ roots"</string>
     <string name="drawer_close" msgid="4263880768630848848">"លាក់ roots"</string>
     <string name="save_error" msgid="8631128801982095782">"បានបរាជ័យក្នុងការរក្សាទុកឯកសារ"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">កំពុង​លុបធាតុ <xliff:g id="COUNT_0">%1$d</xliff:g> ។</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"មិនធ្វើវិញ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"កំពុងរៀបចំចម្លង…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"កំពុង​រៀបចំ​បង្ហាប់…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"កំពុង​រៀបចំ​ស្រង់…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"កំពុងរៀបចំផ្លាស់ទី…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"កំពុងរៀបចំលុប…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"កំពុងរៀបចំ..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"កំពុងរៀបចំ..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"កំពុងរៀបចំ..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"កំពុងរៀបចំ..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"កំពុងរៀបចំ..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">មិនអាច​ចម្លងធាតុ <xliff:g id="COUNT_1">%1$d</xliff:g> បានទេ</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> នៅលើ <xliff:g id="STORAGE"><i>^3</i></xliff:g> ឬ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ឬ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការទិន្នន័យរបស់អ្នក រាប់បញ្ចូលទាំងរូបថត និងវីដេអូ នៅលើ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ឬ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"កុំសួរ​ម្ដងទៀត"</string>
     <string name="allow" msgid="1275746941353040309">"អនុញ្ញាត"</string>
     <string name="deny" msgid="5127201668078153379">"បដិសេធ"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"បណ្ណសារ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"ចម្លងជាន់ពីលើ <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"បន្ត​នៅផ្ទៃ​ខាងក្រោយ"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">បាន​ជ្រើសរើស <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">បាន​ជ្រើសរើស <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ឯកសារ​ថ្មីៗ​នៅលើទូរសព្ទ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ឯកសារ​នៅលើទូរសព្ទ"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> នៅលើ​ទូរសព្ទ"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"ឯកសារ​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"ឯកសារ​ពី <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"ឯកសារ​ពី <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"រូបភាពថ្មីៗ​នៅលើ​ទូរសព្ទ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"រូបភាព​នៅលើ​ទូរសព្ទ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"រូបភាព​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"រូបភាព​ពី <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"រូបភាព​ពី <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"រូបភាព"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"សំឡេង"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"វីដេអូ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ឯកសារ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ឈ្មោះ​ថត"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ឈ្មោះ​ថ្មី"</string>
+    <string name="preview_file" msgid="4056622696305432343">"មើលឯកសារ <xliff:g id="FILENAME">%1$s</xliff:g> សាកល្បង"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"រុករក​ឯកសារ​នៅក្នុង​កម្មវិធី​ផ្សេងទៀត"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"អនាមិក"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"អនុញ្ញាត​ឱ្យ​ចូលប្រើ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"អនុញ្ញាត​ឱ្យ​ចូលប្រើ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" នៅលើ \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ការធ្វើ​បែបនេះ​នឹង​អនុញ្ញាត​ឱ្យ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" អាច​ចូលប្រើ​ឯកសារ​ទាំងអស់​ដែល​កំពុងផ្ទុក​នៅក្រោម​ទីតាំង​នេះ​បានពេញលេញ រួមទាំងខ្លឹមសារ​នាពេលខាងមុខ​ផ្សេងទៀត​ដែល​ផ្ទុក​នៅទីនេះ។"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ស្វែងរក​ទូរសព្ទ​នេះ"</string>
 </resources>
diff --git a/res/values-kn/config.xml b/res/values-kn/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-kn/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 920af9d..c38cd63 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ಅಳಿಸಿ"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"ಎಲ್ಲವನ್ನೂ ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ಇವುಗಳನ್ನು ವಿಂಗಡಿಸಿ..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"ಇದಕ್ಕೆ ನಕಲಿಸಿ…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ಇದಕ್ಕೆ ಸರಿಸು…"</string>
     <string name="menu_compress" msgid="37539111904724188">"ಕುಗ್ಗಿಸಿ"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ಪ್ರಕಾರ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ಗಾತ್ರ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ಮಾರ್ಪಾಡು"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ಫೈಲ್ ಹೆಸರು (A ಯಿಂದ Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ಪ್ರಕಾರ (A ಯಿಂದ Z ವರೆಗೆ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ಗಾತ್ರ (ಚಿಕ್ಕದು)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ಮಾರ್ಪಡಿಸಲಾಗಿದೆ (ಹಳೆಯದು ಮೊದಲು)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ಫೈಲ್ ಹೆಸರು (Z ನಿಂದ A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ಪ್ರಕಾರ (Z ನಿಂದ A ವರೆಗೆ)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ಗಾತ್ರ (ದೊಡ್ಡದು)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ಮಾರ್ಪಡಿಸಲಾಗಿದೆ (ಹೊಸತು ಮೊದಲಿಗೆ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ಈ ಪ್ರಕಾರ ವಿಂಗಡಿಸಿ"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> ಪ್ರಕಾರ ವಿಂಗಡಿಸಲಾಗಿದೆ"</string>
     <string name="directory_items" msgid="6645621978998614003">"ಐಟಂಗಳ ಸಂಖ್ಯೆ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ಆರೋಹಣ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ಅವರೋಹಣ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ತೆರೆಯಿರಿ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ರೂಟ್‌ಗಳನ್ನು ತೋರಿಸು"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ರೂಟ್‌ಗಳನ್ನು ಮರೆಮಾಡು"</string>
     <string name="save_error" msgid="8631128801982095782">"ಡಾಕ್ಯುಮೆಂಟ್ ಉಳಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ಐಟಂಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"ರದ್ದುಮಾಡಿ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"ಕುಗ್ಗಿಸಲು ತಯಾರಿ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"ಹೊರತೆಗೆಯಲು ಸಿದ್ಧವಾಗುತ್ತಿದೆ..."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ಸರಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ಅಳಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>ಐಟಂ ಅನ್ನು ನಕಲು ಮಾಡಲಾಗಲಿಲ್ಲ</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> ರಲ್ಲಿ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಗೆ ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ಸಂಗ್ರಹಣೆಯಲ್ಲಿನ ಪೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
     <string name="allow" msgid="1275746941353040309">"ಅನುಮತಿಸಿ"</string>
     <string name="deny" msgid="5127201668078153379">"ನಿರಾಕರಿಸಿ"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ಅನ್ನು ತಿದ್ದಿಬರೆಯಬೇಕೇ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಮುಂದುವರಿಯಿರಿ"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ಫೋನ್‌ನಲ್ಲಿನ ಇತ್ತೀಚಿನ ಫೈಲ್‌ಗಳು"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ಫೋನ್‌ನಲ್ಲಿನ ಫೈಲ್‌ಗಳು"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ಫೋನ್‌ನಲ್ಲಿನ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿನ ಫೈಲ್‌ಗಳು"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> ನಿಂದ ಫೈಲ್‌ಗಳು"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> ನಿಂದ ಫೈಲ್‌ಗಳು"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ಫೋನ್‌ನಲ್ಲಿ ಇತ್ತೀಚಿನ ಚಿತ್ರಗಳು"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ಫೋನ್‌ನಲ್ಲಿರುವ ಚಿತ್ರಗಳು"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿರುವ ಚಿತ್ರಗಳು"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>ನಿಂದ ಚಿತ್ರಗಳು"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> ನಿಂದ ಚಿತ್ರಗಳು"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ಚಿತ್ರಗಳು"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ಆಡಿಯೊ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ವೀಡಿಯೊಗಳು"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳು"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ಫೋಲ್ಡರ್ ಹೆಸರು"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ಹೊಸ ಹೆಸರು"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ಫೈಲ್‌ ಅನ್ನು ಪೂರ್ವವೀಕ್ಷಿಸಿ"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ಇತರ ಆ್ಯಪ್‌ಗಳಲ್ಲಿರುವ ಫೈಲ್‌ಗಳನ್ನು ಬ್ರೌಸ್ ಮಾಡಿ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ಅನಾಮಧೇಯ"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ಗೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ಇದು ಈ ಸ್ಥಾನದಲ್ಲಿ ಪ್ರಸ್ತುತವಾಗಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಫೈಲ್‌ಗಳಿಗೆ ಮತ್ತು ಭವಿಷ್ಯದಲ್ಲಿ ಸಂಗ್ರಹವಾಗುವ ಎಲ್ಲಾ ವಿಷಯಕ್ಕೆ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ಪೂರ್ಣ ಪ್ರವೇಶ ನೀಡುತ್ತದೆ."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ಈ ಫೋನ್ ಹುಡುಕಿ"</string>
 </resources>
diff --git a/res/values-ko/config.xml b/res/values-ko/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ko/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d2072cd..20f2a6c 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"공유"</string>
     <string name="menu_delete" msgid="1022254131543256626">"삭제"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"모두 선택"</string>
+    <string name="menu_select" msgid="1366061076507142387">"선택"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"정렬 기준..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"다음으로 복사:"</string>
     <string name="menu_move" msgid="2310760789561129882">"다음으로 이동:"</string>
     <string name="menu_compress" msgid="37539111904724188">"압축"</string>
@@ -65,15 +67,26 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"형식"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"크기"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"마지막 수정 시간"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"파일 이름(A~Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"형식(A~Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"크기(작은 파일순)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"수정된 날짜(오래된 날짜순)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"파일 이름(Z~A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"형식(Z~A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"크기(큰 파일순)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"수정된 날짜(최근 날짜순)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"정렬 기준"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g>순으로 정렬됨"</string>
     <string name="directory_items" msgid="6645621978998614003">"항목 수"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"오름차순"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"내림차순"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> 열기"</string>
     <string name="drawer_open" msgid="8071673398187261741">"루트 표시"</string>
     <string name="drawer_close" msgid="4263880768630848848">"루트 숨기기"</string>
     <string name="save_error" msgid="8631128801982095782">"문서를 저장하지 못했습니다."</string>
     <string name="create_error" msgid="3092144450044861994">"폴더를 만들지 못했습니다."</string>
     <string name="query_error" msgid="6625421453613879336">"현재 콘텐츠를 로드할 수 없습니다."</string>
-    <string name="root_recent" msgid="1080156975424341623">"최근순"</string>
+    <string name="root_recent" msgid="1080156975424341623">"최근"</string>
     <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> 남음"</string>
     <string name="root_type_service" msgid="6521366147466512289">"저장용량 서비스"</string>
     <string name="root_type_shortcut" msgid="6059343175525442279">"바로가기"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개의 항목을 삭제 중입니다.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"실행취소"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"사본 준비 중…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"압축 준비 중…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"추출 준비 중…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"이동 준비 중…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"삭제 준비 중..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"준비 중..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"준비 중..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"준비 중..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"준비 중..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"준비 중..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개의 항목을 복사할 수 없음</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="STORAGE"><i>^3</i></xliff:g>에서 <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>에서 <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>에서 사진, 동영상 등 <xliff:g id="STORAGE"><i>^2</i></xliff:g>의 내 데이터에 액세스하도록 허용하시겠습니까?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"다시 묻지 않음"</string>
     <string name="allow" msgid="1275746941353040309">"허용"</string>
     <string name="deny" msgid="5127201668078153379">"거부"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"보관처리<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g>을(를) 덮어쓰시겠습니까?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"백그라운드에서 계속"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 선택됨</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 선택됨</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"휴대전화의 최근 파일"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"휴대전화의 파일"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"휴대전화의 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>의 파일"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>의 파일"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g>의 파일/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"휴대전화에 있는 최근 이미지"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"휴대전화에 있는 이미지"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>에 있는 이미지"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>의 이미지"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>의 이미지/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"이미지"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"오디오"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"동영상"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"문서"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"폴더 이름"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"새 이름"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> 파일 미리보기"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"다른 앱의 파일 탐색"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"익명"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\'<xliff:g id="DIRECTORY">%1$s</xliff:g>\'에 액세스하도록 허용"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\'<xliff:g id="ROOT">%2$s</xliff:g>\'에서 \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\'에 액세스하도록 허용하시겠습니까?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"\'<xliff:g id="APPNAME">%1$s</xliff:g>\'이(가) 현재 이 위치에 저장된 모든 파일과 향후 여기에 저장되는 모든 콘텐츠에 대해 완전한 액세스 권한을 갖게 됩니다."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"이 휴대전화 검색"</string>
 </resources>
diff --git a/res/values-ky/config.xml b/res/values-ky/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ky/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index b92c8db..fc5aaaf 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Бөлүшүү"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Жок кылуу"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Бардыгын тандоо"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Тандоо"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Төмөнкү боюнча иреттөө…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Төмөнкүгө көчүрүү…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Төмөнкүгө жылдыруу..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Кысуу"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Түрү"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Өлчөмү"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Өзгөрүлгөн"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Файлдын аталышы (А-Я)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Түрү (А-Я)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Өлчөмү (эң кичинекейинен баштап)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Өзгөртүлдү (эң эскисинен баштап)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Файлдын аталышы (Я-А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Түрү (Я-А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Өлчөмү (эң чоңунан баштап)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Өзгөртүлдү (эң жаңысынан баштап)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Төмөнкү боюнча иреттөө:"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> боюнча иреттелди"</string>
     <string name="directory_items" msgid="6645621978998614003">"Элементтердин саны"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Чоңойгон ыраатта"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Кичирейген ыраатта"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосун ачуу"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Папкаларды көрсөтүү"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Папкаларды жашыруу"</string>
     <string name="save_error" msgid="8631128801982095782">"Документтер сакталбай калды"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> нерсе жок кылынууда.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Кайтаруу"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Көчүрүүгө даярдалууда…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Кысууга даярдалууда…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Чыгарууга даярдалууда…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Жылдырууга даярдалууда…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Жок кылууга даярдалууда…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Даярдалууда…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Даярдалууда…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Даярдалууда…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Даярдалууда…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Даярдалууда…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> нерсе көчүрүлбөй койду</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^3</i></xliff:g> түзмөгүндөгү <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> папканы пайдалануу мүмкүнчүлүгү берилсинби?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогун пайдалануу мүмкүнчүлүгү берилсинби?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^2</i></xliff:g> түзмөгүндөгү дайындарыңыз, сүрөттөрүңүз жана видеолоруңузду пайдалануу мүмкүнчүлүгү берилсинби?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Экинчи суралбасын"</string>
     <string name="allow" msgid="1275746941353040309">"Уруксат берүү"</string>
     <string name="deny" msgid="5127201668078153379">"Жок"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"архив<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> файлынын үстүнөн жазылсынбы?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Фондо улантуу"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> тандалды</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> тандалды</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Телефондогу акыркы файлдар"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Телефондогу файлдар"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Телефондогу <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүндөгү файлдар"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> сактагычындагы файлдар"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> сактагычындагы файлдар / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Телефондогу акыркы сүрөттөр"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Телефондогу сүрөттөр"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүндөгү сүрөттөр"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> сактагычындагы сүрөттөр"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> аккаунтунун сүрөттөрү"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Сүрөттөр"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аудио"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Видеолор"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документтер"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Папканын аталышы"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Жаңы аталыш"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> файлын алдын ала көрүү"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Башка колдонмолордон файлдарды карап чыгуу"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Жашыруун"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" папкасын колдонууга уруксат берүү"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" сактагычында жайгашкан \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" папкасына уруксат берилсинби?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Ушуну менен \"<xliff:g id="APPNAME">%1$s</xliff:g>\" колдонмосуна ушул жерде сакталган жана келечекте сактала турган бардык файлдарга кирүү мүмкүнчүлүгү берилет."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Ушул телефондо издөө"</string>
 </resources>
diff --git a/res/values-lo/config.xml b/res/values-lo/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-lo/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 320075e..fb27c19 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"ແບ່ງປັນ"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ລຶບ"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"ເລືອກທັງຫມົດ"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ເລືອກ"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ຈັດຮຽງຕາມ..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"ສຳເນົາໄປໃສ່..."</string>
     <string name="menu_move" msgid="2310760789561129882">"ຍ້າຍໄປໃສ່..."</string>
     <string name="menu_compress" msgid="37539111904724188">"ບີບອັດ"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ປະເພດ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ຂະໜາດ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ແກ້ໄຂເມື່ອ"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ຊື່ໄຟລ໌ (A ຫາ Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ປະເພດ (A ຫາ Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ຂະໜາດ (ນ້ອຍສຸດກ່ອນ)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ແກ້ໄຂແລ້ວ (ເກົ່າສຸດກ່ອນ)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ຊື່ໄຟລ໌ (Z ຫາ A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ປະເພດ (Z ຫາ A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ຂະໜາດ (ໃຫຍ່ສຸດກ່ອນ)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ແກ້ໄຂແລ້ວ (ໃໝ່ສຸດກ່ອນ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ຈັດຮຽງຕາມ"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"ຈັດຮຽງຕາມ <xliff:g id="LABEL">%s</xliff:g> ແລ້ວ"</string>
     <string name="directory_items" msgid="6645621978998614003">"ຈໍານວນລາຍການ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ໃຫຍ່ຫານ້ອຍ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ນ້ອຍຫາໃຫຍ່"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"ເປີດ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ສະແດງ roots"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ເຊື່ອງ roots"</string>
     <string name="save_error" msgid="8631128801982095782">"ການບັນທຶກເອກະສານບໍ່ສຳເລັດ"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">ກຳ​ລັງ​ລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"ຍົກເລີກ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"ກຳລັງກຽມການສຳເນົາ…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"ກຳລັງກຽມບີບໄຟລ໌…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"ກຳລັງກະກຽມແຕກໄຟລ໌..."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ກຳລັງກະກຽມຍ້າຍ…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ກຳລັງກະກຽມການລຶບ…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"ກຳລັງກະກຽມ..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"ກຳລັງກະກຽມ..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"ກຳລັງກະກຽມ..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"ກຳລັງກະກຽມ..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"ກຳລັງກະກຽມ..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">ບໍ່ສາມາດສຳເນົາໄຟລ໌ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້.</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"ອະນຸຍາດສິດເຂົ້າເຖິງໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເພື່ອເຂົ້າໄດເຣກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ຢູ່ <xliff:g id="STORAGE"><i>^3</i></xliff:g> ບໍ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"ອະນຸມັດ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ໃຫ້ເຂົ້າຫາໄດເຣັກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ບໍ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"ອະນຸມັດ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນຂອງທ່ານ ຮວມທັງຮູບພາບ ແລະ ວິດີໂອໃນ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ບໍ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ບໍ່ຕ້ອງຖາມຄືນ"</string>
     <string name="allow" msgid="1275746941353040309">"ອະນຸມັດ"</string>
     <string name="deny" msgid="5127201668078153379">"ປະຕິເສດ"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"ຂຽນທັບ <xliff:g id="NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ສືບຕໍ່ໃນພື້ນຫຼັງ"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">ເລືອກ <xliff:g id="COUNT_1">%1$d</xliff:g> ແລ້ວ</item>
+      <item quantity="one">ເລືອກ <xliff:g id="COUNT_0">%1$d</xliff:g> ແລ້ວ</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ໄຟລ໌ຫຼ້າສຸດຢູ່ໂທລະສັບ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ໄຟລ໌ຢູ່ໂທລະສັບ"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> ຢູ່ໂທລະສັບ"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"ໄຟລ໌ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"ໄຟລ໌ຈາກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"ໄຟລ໌ຈາກ <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ຮູບຫຼ້າສຸດຢູ່ໂທລະສັບ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ຮູບຢູ່ໂທລະສັບ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"ຮູບຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"ຮູບພາບຈາກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"ຮູບຈາກ <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ຮູບພາບ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ສຽງ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ວິດີໂອ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ເອກະສານ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ຊື່ໂຟນເດີ"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ຊື່ໃໝ່"</string>
+    <string name="preview_file" msgid="4056622696305432343">"ເບິ່ງຕົວຢ່າງໄຟລ໌ <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ເລືອກໄຟລ໌ໃນແອັບອື່ນ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ບໍ່ລະບຸຊື່"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"ອະນຸຍາດການເຂົ້າເຖິງ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"ອະນຸຍາດໃຫ້ເຂົ້າເຖິງ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ຢູ່ \"<xliff:g id="ROOT">%2$s</xliff:g>\" ໄດ້ບໍ?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ມັນຈະອະນຸຍາດໃຫ້ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ເຂົ້າເຖິງໄຟລ໌ທັງໝົດທີ່ຕອນນີ້ບັນທຶກໄວ້ຢູ່ບ່ອນນີ້ຢ່າງເຕັມຮູບແບບ ແລະ ຮວມທັງເນື້ອຫາໃນອະນາຄົດທີ່ບັນທຶກໄວ້ບ່ອນນີ້ນຳ."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ຊອກຫາໂທລະສັບໜ່ວຍນີ້"</string>
 </resources>
diff --git a/res/values-lt/config.xml b/res/values-lt/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-lt/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index ec80676..00e2840 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Bendrinti"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Ištrinti"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Pasirinkti viską"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Pasirinkti"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Rūšiuoti pagal..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopijuoti į..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Perkelti į…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Suglaudinti"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipas"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Dydis"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Pakeista"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Failo pav. (nuo A iki Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipas (nuo A iki Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Dydis (pirmiau mažiausi)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Pakeista (pirm. sen.)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Failo pav. (nuo Z iki A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipas (nuo Z iki A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Dydis (pirm. didžiausi)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Pakeista (pirm. nauj.)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Rūšiuoti pagal"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Rūšiuojama pagal <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Elementų skaičius"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Didėjimo tvarka"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Mažėjimo tvarka"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Atidaryti programą „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Rodyti šaknis"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Slėpti šaknis"</string>
     <string name="save_error" msgid="8631128801982095782">"Nepavyko išsaugoti dokumento"</string>
@@ -122,11 +135,11 @@
       <item quantity="other">Ištrinama <xliff:g id="COUNT_1">%1$d</xliff:g> elementų.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Anuliuoti"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Ruošiamasi kopijuoti…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Ruošiamasi glaudinti…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Ruošiamasi išskleisti…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Ruošiamasi perkelti…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Ruošiama ištrinti…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Ruošiama..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Ruošiama..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Ruošiama..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Ruošiama..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Ruošiama..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Suteikti programai „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie duomenų, įskaitant nuotraukas ir vaizdo įrašus, <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Daugiau neklausti"</string>
     <string name="allow" msgid="1275746941353040309">"Leisti"</string>
     <string name="deny" msgid="5127201668078153379">"Atmesti"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archyvas<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Perrašyti „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Tęsti fone"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Pasirinktas <xliff:g id="COUNT_1">%1$d</xliff:g> elementas</item>
+      <item quantity="few">Pasirinkti <xliff:g id="COUNT_1">%1$d</xliff:g> elementai</item>
+      <item quantity="many">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item>
+      <item quantity="other">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elementų</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Naujausi failai telefone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Failai telefone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> telefone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Failai „<xliff:g id="DEVICE">%1$s</xliff:g>“ įrenginyje"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Failai iš <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Failai iš <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Naujausi vaizdai telefone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Vaizdai telefone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Vaizdai „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Vaizdai iš <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Vaizdai iš <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Vaizdai"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Garsas"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vaizdo įrašai"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumentai"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Aplanko pavadinimas"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Naujas pavadinimas"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Peržiūrėti failą „<xliff:g id="FILENAME">%1$s</xliff:g>“"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Failų naršymas kitose programos"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anoniminė"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Leisti pasiekti „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Leisti pasiekti „<xliff:g id="DIRECTORY">%1$s</xliff:g>“, esantį „<xliff:g id="ROOT">%2$s</xliff:g>“?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ galės pasiekti visus šiuo metu šioje vietoje saugomus failus ir visą turinį, kuris bus čia saugomas."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Ieškoti šiame telefone"</string>
 </resources>
diff --git a/res/values-lv/config.xml b/res/values-lv/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-lv/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 16e50a8..b9ec6c2 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Kopīgot"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Dzēst"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Atlasīt visus"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Atlasīt"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Kārtot pēc..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopēt…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Pārvietot uz…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Saspiest"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Veids"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Lielums"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Izmaiņas"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Faila nosaukums (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Veids (A–Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Lielums (visp. mazākie)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Pārv. (vispirms vecākie)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Faila nosaukums (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Veids (Z–A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Lielums (visp. lielākie)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Pārv. (visp. jaunākie)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Kārtošana"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sakārtoti pēc: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Vienumu skaits"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Augošā secībā"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Dilstošā secībā"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Atvērt lietotni <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Rādīt saknes"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Slēpt saknes"</string>
     <string name="save_error" msgid="8631128801982095782">"Neizdevās saglabāt dokumentu."</string>
@@ -117,11 +130,11 @@
       <item quantity="other">Tiek dzēsti <xliff:g id="COUNT_1">%1$d</xliff:g> vienumi.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Atsaukt"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Notiek sagatavošanās kopēšanai…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Notiek gatavošanās saspiešanai…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Tiek sagatavoti izvilkšanai paredzētie dati."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Sagatavošanās pārvietošanai…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Notiek sagatavošanās dzēšanai…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Notiek sagatavošana..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Notiek sagatavošana..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Notiek sagatavošana..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Notiek sagatavošana..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Notiek sagatavošana..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> no <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="zero">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> vienumus</item>
@@ -188,7 +201,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Vai piešķirt lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļuvi direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> šajā krātuvē: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Vai piešķirt lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļuvi direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Vai piešķirt lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļuvi jūsu datiem, tostarp fotoattēliem un videoklipiem, šajā krātuvē: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Turpmāk vairs nejautāt"</string>
     <string name="allow" msgid="1275746941353040309">"Atļaut"</string>
     <string name="deny" msgid="5127201668078153379">"Noraidīt"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -227,4 +239,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhivs<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Vai pārrakstīt failu <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Turpināt izpildi fonā"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīts</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Jaunākie faili tālrunī"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Faili tālrunī"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> tālrunī"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Faili ierīcē <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Faili no pakalpojuma <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Faili no pakalpojuma <xliff:g id="LABEL">%1$s</xliff:g> (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Pēdējie attēli tālrunī"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Attēli tālrunī"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Attēli ierīcē <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Attēli no: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Attēli no: <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Attēli"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videoklipi"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Mapes nosaukums"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Jauns nosaukums"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Priekšskatīt failu <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Failu pārlūkošana citās lietotnēs"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonīma"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Atļaut piekļuvi mapei “<xliff:g id="DIRECTORY">%1$s</xliff:g>”"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Vai atļaut piekļuvi mapei “<xliff:g id="DIRECTORY">%1$s</xliff:g>” šeit: <xliff:g id="ROOT">%2$s</xliff:g>?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Lietotnei <xliff:g id="APPNAME">%1$s</xliff:g> tiks piešķirta pilna piekļuve visiem failiem, kas pašlaik tiek glabāti šajā vietā, kā arī visam saturam, kas turpmāk šeit tiks glabāts."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Meklēt šajā tālrunī"</string>
 </resources>
diff --git a/res/values-mk/config.xml b/res/values-mk/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-mk/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 7322e73..60bcbab 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Сподели"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Избриши"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Избери ги сите"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Избери"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Подреди според…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Копирај во…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Премести во…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Компресирај"</string>
@@ -48,7 +50,7 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Копирај"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Залепи"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"Залепи во папка"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"Прикажи внатр. меморија"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Прикажи внатрешен капацитет"</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"Сокриј внатр. меморија"</string>
     <string name="button_select" msgid="240863497069321364">"Избери"</string>
     <string name="button_copy" msgid="8219059853840996027">"Копирај"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Големина"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Изменето"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Име на датотека (А до Ш)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Тип (А до Ш)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Големина (најмали први)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Изменети (прво најстари)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Име на датотека (Ш до А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Тип (Ш до А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Големина (најгол. први)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Изменети (прво најнови)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Подреди според"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Сортирани според <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Број на ставки"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Растечко"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Опаѓачко"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Отворете <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Прикажи корени"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Сокриј корени"</string>
     <string name="save_error" msgid="8631128801982095782">"Документот не успеа да се зачува"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Се бришат <xliff:g id="COUNT_1">%1$d</xliff:g> ставки.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Врати"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Се подготвува за копирање…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Се подготвува за компримирање…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Се подготвува за извлекување…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Се подготвува за преместување…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Се подготвува за бришење…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Се подготвува…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Се подготвува…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Се подготвува…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Се подготвува…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Се подготвува…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Не можеше да се копира <xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до вашите податоци, вклучувајќи фотографии и видеа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Не прашувај повторно"</string>
     <string name="allow" msgid="1275746941353040309">"Дозволи"</string>
     <string name="deny" msgid="5127201668078153379">"Одбиј"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"архива<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Да се презапише <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Продолжи во заднина"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Избрана е <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Избрани се <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Неодамнешни датотеки на телефонот"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Датотеки на телефонот"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> на телефонот"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Датотеки на <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Датотеки од <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Датотеки од <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Неодамнешни слики на телефонот"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Слики на телефонот"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Слики на <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Слики од <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Слики од <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Слики"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аудио"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Видеа"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документи"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Име на папка"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Ново име"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Прегледајте ја датотеката <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Прелистувајте датотеки во други апликации"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Анонимна"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Дозволи пристап до „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Да се дозволи пристап до „<xliff:g id="DIRECTORY">%1$s</xliff:g>“ на „<xliff:g id="ROOT">%2$s</xliff:g>“?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Ќе ѝ се дозволи на <xliff:g id="APPNAME">%1$s</xliff:g> да има целосен пристап до сите датотеки моментално складирани на оваа локација и до сите идни содржини складирани тука."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Пребарајте го телефонов"</string>
 </resources>
diff --git a/res/values-ml/config.xml b/res/values-ml/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ml/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index c7692e7..30b0b2a 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"പങ്കിടുക"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ഇല്ലാതാക്കുക"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"എല്ലാം തിരഞ്ഞെടുക്കുക"</string>
+    <string name="menu_select" msgid="1366061076507142387">"തിരഞ്ഞെടുക്കുക"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ഇപ്രകാരം അടുക്കുക..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"ഇതിൽ പകർത്തുക…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ഇതിലേക്ക് നീക്കുക..."</string>
     <string name="menu_compress" msgid="37539111904724188">"കംപ്രസ്സുചെയ്യുക"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"തരം"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"വലുപ്പം"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"പരിഷ്‌ക്കരിച്ചു"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ഫയലിൻ്റെ പേര് (A - Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ടൈപ്പ് ചെയ്യൂ (A - Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"വലുപ്പം (ചെറുത് ആദ്യം)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"പരിഷ്ക്കരിച്ചത് (പഴയത് ആദ്യം)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ഫയലിൻ്റെ പേര് (Z - A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ടൈപ്പ് ചെയ്യൂ (Z - A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"വലുപ്പം (വലുത് ആദ്യം)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"പരിഷ്ക്കരിച്ചത് (പുതിയത് ആദ്യം)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ഇപ്രകാരം അടുക്കുക"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g>-ൻ്റെ അടിസ്ഥാനത്തിൽ അടുക്കിയിരിക്കുന്നു"</string>
     <string name="directory_items" msgid="6645621978998614003">"ഇനങ്ങളുടെ എണ്ണം"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ആരോഹണം"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"അവരോഹണം"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> തുറക്കുക"</string>
     <string name="drawer_open" msgid="8071673398187261741">"റൂട്ടുകൾ ദൃശ്യമാക്കുക"</string>
     <string name="drawer_close" msgid="4263880768630848848">"റൂട്ടുകൾ മറയ്‌ക്കുക"</string>
     <string name="save_error" msgid="8631128801982095782">"പ്രമാണം സംരക്ഷിക്കുന്നതിൽ പരാജയപ്പെട്ടു"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഇനം ‌ഇല്ലാതാക്കുന്നു.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"പഴയപടിയാക്കുക"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"പകർപ്പിനായി തയ്യാറെടുക്കുന്നു…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"കംപ്രസ്സിന് തയ്യാറെടുക്കുന്നു…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"എക്‌സ്ട്രാക്റ്റിന് തയ്യാറെടുക്കുന്നു…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"നീക്കാനൊരുങ്ങുന്നു…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ഇല്ലാതാക്കാൻ തയ്യാറെടുക്കുന്നു..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"തയ്യാറെടുക്കുന്നു..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"തയ്യാറെടുക്കുന്നു..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"തയ്യാറെടുക്കുന്നു..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"തയ്യാറെടുക്കുന്നു..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"തയ്യാറെടുക്കുന്നു..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഇനങ്ങൾ ‌പകർത്താനായില്ല</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> സ്റ്റോറേജിലെ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്റ്ററിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്ടറിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> സ്റ്റോറേജിലെ ഫോട്ടോകളും വീഡിയോകളും ഉൾപ്പെടെ, നിങ്ങളുടെ ഡാറ്റയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ്സ് അനുവദിക്കണോ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
     <string name="allow" msgid="1275746941353040309">"അനുവദിക്കുക"</string>
     <string name="deny" msgid="5127201668078153379">"നിരസിക്കുക"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"ആർക്കൈവ്<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> മാറ്റിയെഴുതണോ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"പശ്ചാത്തലത്തിൽ തുടരുക"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ഫോണിലെ അടുത്തിടെയുള്ള ഫയലുകൾ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ഫോണിലെ ഫയലുകൾ"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ഫോണിലെ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>-ലെ ഫയലുകൾ"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> എന്നതിൽ നിന്നുള്ള ഫയലുകൾ"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> എന്നതിൽ നിന്നുള്ള ഫയലുകൾ"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ഫോണിലെ അടുത്തിടെയുള്ള ചിത്രങ്ങൾ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ഫോണിലെ ചിത്രങ്ങൾ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> എന്ന ഉപകരണത്തിലെ ചിത്രങ്ങൾ"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>-ലെ ചിത്രങ്ങൾ"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> എന്നതിൽ നിന്നുള്ള ചിത്രങ്ങൾ"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ചിത്രങ്ങൾ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ഓഡിയോ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"വീഡിയോകൾ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ഡോക്യുമെന്റുകൾ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ഫോൾഡറിന്റെ പേര്"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"പുതിയ പേര്"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ഫയൽ പ്രിവ്യൂ ചെയ്യുക"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ഫയലുകള്‍ മറ്റ് ആപ്പുകളില്‍ ബ്രൗസ് ചെയ്യുക"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"അജ്ഞാതം"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" എന്നതിലേക്ക് ആക്‌സസ് അനുവദിക്കുക"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" എന്നതിൽ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" എന്നതിലേക്ക് ആക്‌സസ് നൽകണോ?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ഇത് \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ആപ്പിന് ഈ ലൊക്കേഷനിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ ഫയലുകളിലേക്കും ഭാവിയിൽ ഇവിടെ സംഭരിക്കപ്പെടുന്ന എല്ലാ ഉള്ളടക്കത്തിലേക്കും പൂർണ്ണ ആക്‌സസ് അനുവദിക്കും."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ഈ ഫോൺ തിരയുക"</string>
 </resources>
diff --git a/res/values-mn/config.xml b/res/values-mn/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-mn/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 3988b41..0a68e23 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Хуваалцах"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Устгах"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Бүгдийг сонгох"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Сонгох"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Дараахаар эрэмбэлэх..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Дараахад хуулах..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Дараахад зөөх"</string>
     <string name="menu_compress" msgid="37539111904724188">"Шахах"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Төрөл"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Хэмжээ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Өөрчилсөн"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Файлын нэр (А - Я)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Төрөл (A - Я)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Хэмжээ (жижиг нь эхэнд)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Өөрчилсөн (хуучин нь эхэнд)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Файлын нэр (Я - А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Төрөл (Я - А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Хэмжээ (том нь эхэнд)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Өөрчилсөн (шинэ нь эхэнд)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Дараахаар эрэмбэлэх"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g>-р эрэмбэлсэн"</string>
     <string name="directory_items" msgid="6645621978998614003">"Зүйлийн тоо"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Дээшилж буй"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Буурч буй"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g>-г нээх"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Документын санг харуулах"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Документын санг нуух"</string>
     <string name="save_error" msgid="8631128801982095782">"Документыг хадгалж чадсангүй"</string>
@@ -79,7 +92,7 @@
     <string name="root_type_shortcut" msgid="6059343175525442279">"Товчлол"</string>
     <string name="root_type_device" msgid="1713604128005476585">"Төхөөрөмж"</string>
     <string name="root_type_apps" msgid="8646073235029886342">"Бусад апп"</string>
-    <string name="empty" msgid="5300254272613103004">"Зүйл алга"</string>
+    <string name="empty" msgid="5300254272613103004">"Хоосон"</string>
     <string name="no_results" msgid="2371026325236359209">"%1$s-д тохирох зүйл алга"</string>
     <string name="toast_no_application" msgid="7555319548595113121">"Файлыг нээх боломжгүй байна"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Архивын файлыг нээх боломжгүй"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> зүйлийг устгаж байна.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Буцаах"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Хуулахад бэлдэж байна..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Шахахад бэлдэж байна..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Задлахад бэлдэж байна..."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Зөөхөд бэлтгэж байна..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Устгахад бэлдэж байна..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Бэлтгэж байна..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Бэлтгэж байна..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Бэлтгэж байна..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Бэлтгэж байна..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Бэлтгэж байна..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> зүйлийг хуулж чадсангүй</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g>-д байгаа <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандах эрхийг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д олгох уу?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандах эрхийг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д олгох уу?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>-д байгаа зураг, видео зэрэг таны өгөгдөлд хандах эрхийг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д олгох уу?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Дахин бүү асуу"</string>
     <string name="allow" msgid="1275746941353040309">"Зөвшөөрөх"</string>
     <string name="deny" msgid="5127201668078153379">"Татгалзах"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"архив<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g>-г дарж бичих үү?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Цаана үргэлжлүүлэх"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>-г сонгосон</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>-г сонгосон</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Утсан дээрх саяхны файлууд"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Утсан дээрх файлууд"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Утсан дээрх <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> дээрх файлууд"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>-н файлууд"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>-н файлууд"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Утсан дээрх саяхны зураг"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Утсан дээрх зураг"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> дээрх зураг"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>-н зураг"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>-н зураг"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Зураг"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аудио"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Видео"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Фолдерын нэр"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Шинэ нэр"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> файлыг урьдчилан үзэх"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Бусад аппын файлыг үзэх"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Үл мэдэгдэх"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"-н хандалтыг зөвшөөрөх"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"-н хандалтыг \"<xliff:g id="ROOT">%2$s</xliff:g>\" дээр зөвшөөрөх үү?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Энэ нь \"<xliff:g id="APPNAME">%1$s</xliff:g>\"-д одоогоор энэ байршилд хадгалсан бүх файл болон үүнд цаашид хадгалах контентод бүрэн хандахыг зөвшөөрнө."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Энэ утсыг хайх"</string>
 </resources>
diff --git a/res/values-mr/config.xml b/res/values-mr/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-mr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 81899f5..59e9631 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -28,14 +28,16 @@
     <string name="menu_grid" msgid="1453636521731880680">"ग्रिड दृश्य"</string>
     <string name="menu_list" msgid="6714267452146410402">"सूची"</string>
     <string name="menu_search" msgid="1876699106790719849">"शोधा"</string>
-    <string name="menu_settings" msgid="6520844520117939047">"संचय सेटिंग्ज"</string>
+    <string name="menu_settings" msgid="6520844520117939047">"स्टोरेज सेटिंग्ज"</string>
     <string name="menu_open" msgid="9092138100049759315">"उघडा"</string>
     <string name="menu_open_with" msgid="5507647065467520229">"यासह उघडा"</string>
     <string name="menu_open_in_new_window" msgid="6686563636123311276">"नवीन विंडोमध्ये उघडा"</string>
     <string name="menu_save" msgid="5195367497138965168">"सेव्ह करा"</string>
-    <string name="menu_share" msgid="4307140947108068356">"सामायिक करा"</string>
+    <string name="menu_share" msgid="4307140947108068356">"शेअर करा"</string>
     <string name="menu_delete" msgid="1022254131543256626">"हटवा"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"सर्व निवडा"</string>
+    <string name="menu_select" msgid="1366061076507142387">"निवडा"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"क्रमानुसार लावा…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"यावर कॉपी करा…"</string>
     <string name="menu_move" msgid="2310760789561129882">"यामध्ये हलवा…"</string>
     <string name="menu_compress" msgid="37539111904724188">"संकुचित करा"</string>
@@ -48,8 +50,8 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"कॉपी करा"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"पेस्ट करा"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"फोल्डरमध्ये पेस्ट करा"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"अंतर्गत संचय दर्शवा"</string>
-    <string name="menu_advanced_hide" msgid="6488381508009246334">"अंतर्गत संचय लपवा"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"अंतर्गत स्टोरेज दर्शवा"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"अंतर्गत स्टोरेज लपवा"</string>
     <string name="button_select" msgid="240863497069321364">"निवडा"</string>
     <string name="button_copy" msgid="8219059853840996027">"कॉपी करा"</string>
     <string name="button_compress" msgid="8951561310857223966">"संकुचित करा"</string>
@@ -65,17 +67,28 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"सुधारित"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"फाइलचे नाव (A ते Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"प्रकार (A ते Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"आकार (सर्वात लहान प्रथम)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"सुधारित (जुने प्रथम)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"फाइलचे नाव (Z ते A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"प्रकार (Z ते A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"आकार (सर्वात मोठे प्रथम)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"सुधारित (नवीनतम प्रथम)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"क्रमानुसार लावा"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> क्रमवारी लावलेले"</string>
     <string name="directory_items" msgid="6645621978998614003">"आयटमची संख्या"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"चढत्या क्रमाने"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"उतरत्या क्रमाने"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> उघडा"</string>
     <string name="drawer_open" msgid="8071673398187261741">"रूट दर्शवा"</string>
     <string name="drawer_close" msgid="4263880768630848848">"रूट लपवा"</string>
-    <string name="save_error" msgid="8631128801982095782">"दस्तऐवज जतन करणे अयशस्वी झाले"</string>
+    <string name="save_error" msgid="8631128801982095782">"दस्तऐवज सेव्ह करणे अयशस्वी झाले"</string>
     <string name="create_error" msgid="3092144450044861994">"फोल्डर तयार करण्यात अयशस्वी झाले"</string>
     <string name="query_error" msgid="6625421453613879336">"याक्षणी सामग्री लोड करू शकत नाही"</string>
     <string name="root_recent" msgid="1080156975424341623">"अलीकडील"</string>
     <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> विनामूल्‍य"</string>
-    <string name="root_type_service" msgid="6521366147466512289">"संचय सेवा"</string>
+    <string name="root_type_service" msgid="6521366147466512289">"स्टोरेज सेवा"</string>
     <string name="root_type_shortcut" msgid="6059343175525442279">"शॉर्टकट"</string>
     <string name="root_type_device" msgid="1713604128005476585">"डिव्हाइसेस"</string>
     <string name="root_type_apps" msgid="8646073235029886342">"अधिक अ‍ॅप्‍स"</string>
@@ -84,7 +97,7 @@
     <string name="toast_no_application" msgid="7555319548595113121">"फाईल उघडू शकत नाही"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"संग्रहणांमध्‍ये फायली उघडू शकत नाही"</string>
     <string name="toast_failed_delete" msgid="3453846588205817591">"काही दस्‍तऐवज हटविण्‍यात अक्षम"</string>
-    <string name="share_via" msgid="8725082736005677161">"द्वारे सामायिक करा"</string>
+    <string name="share_via" msgid="8725082736005677161">"द्वारे शेअर करा"</string>
     <string name="copy_notification_title" msgid="52256435625098456">"फायली कॉपी करणे"</string>
     <string name="compress_notification_title" msgid="6830195148113751021">"फायली संकुचित करत आहे"</string>
     <string name="extract_notification_title" msgid="5067393961754430469">"फायली काढत आहे"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम हटवत आहे.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"पूर्ववत करा"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"कॉपी करण्‍यासाठी तयार करत आहे…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"संकुचित करण्‍यासाठी तयार होत आहे…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"काढण्यासाठी तयार करत आहे..."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"हलविण्‍यास तयार होत आहे…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"हटविण्‍यासाठी तयार करत आहे..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"तयार करत आहे…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"तयार करत आहे…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"तयार करत आहे…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"तयार करत आहे…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"तयार करत आहे…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम कॉपी करु शकलो नाही</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> वर <xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकेवर प्रवेशाची मंजूरी द्यायची?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकेेमध्ये प्रवेश मंजूर करायचा?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला फोटो आणि व्हिडिओंंसह आपल्या डेटामध्ये <xliff:g id="STORAGE"><i>^2</i></xliff:g> वर प्रवेशाची मंजूरी द्यायची?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"पुन्हा विचारू नका"</string>
     <string name="allow" msgid="1275746941353040309">"अनुमती द्या"</string>
     <string name="deny" msgid="5127201668078153379">"नकार द्या"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"संग्रहण<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> अधिलिखित करायचे?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"पार्श्वभूमीमध्ये सुरू ठेवा"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडला</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडले</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"फोनवरील अलीकडील फायली"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"फोनवरील फायली"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"फोनवरील <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> वरील फायली"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> मधील फायली"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> मधील फायली / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"फोनवरील अलीकडील इमेज"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"फोनवरील इमेज"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> वरील इमेज"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> कडील इमेज"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> कडील इमेज"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"इमेज"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ऑडिओ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"व्हिडिओ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"दस्तऐवज"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"फोल्डर नाव"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"नवीन नाव"</string>
+    <string name="preview_file" msgid="4056622696305432343">"फाइल <xliff:g id="FILENAME">%1$s</xliff:g> चे पूर्वावलोकन करा"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"इतर अ‍ॅप्समध्येे फायली ब्राउझ करा"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"अनामित"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ला अ‍ॅक्सेस करण्याची अनुमती द्या"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"हे या स्थानावर सध्या स्टोअर केलेल्या सर्व फायलींच्या आणि भविष्यात स्टोअर केलेल्या आशयाच्या अ‍ॅक्सेसची \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ला अनुमती देईल."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"हा फोन शोधा"</string>
 </resources>
diff --git a/res/values-ms/config.xml b/res/values-ms/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ms/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index d156645..f06d9a0 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Kongsi"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Padam"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Pilih semua"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Pilih"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Isih mengikut…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Salin ke…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Alihkan ke…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Mampatkan"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Jenis"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Saiz"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Diubah suai"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nama fail (A hingga Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Jenis (A hingga Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Saiz (terkecil dahulu)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Diubah suai (lama dulu)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nama fail (Z hingga A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Jenis (Z hingga A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Saiz (terbesar dahulu)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Diubah suai (baru dulu)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Isih mengikut"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Diisih mengikut <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Bilangan item"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Menaik"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Menurun"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Tunjukkan akar"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Sembunyikan akar"</string>
     <string name="save_error" msgid="8631128801982095782">"Gagal menyimpan dokumen"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Memadamkan <xliff:g id="COUNT_0">%1$d</xliff:g> item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Buat asal"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Bersedia untuk menyalin…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Bersedia untuk memampat…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Bersedia untuk mengestrak…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Bersedia untuk mengalih…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Bersedia untuk memadam…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Menyediakan…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Menyediakan…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Menyediakan…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Menyediakan…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Menyediakan…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada data anda, termasuk foto dan video di <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Jangan tanya lagi"</string>
     <string name="allow" msgid="1275746941353040309">"Benarkan"</string>
     <string name="deny" msgid="5127201668078153379">"Tolak"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Tulis ganti <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Teruskan di latar belakang"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Fail terbaharu pada telefon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fail pada telefon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> pada telefon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fail pada <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fail daripada <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fail daripada <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imej terbaharu pada telefon"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imej pada telefon"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imej pada <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imej daripada <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imej daripada <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imej"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumen"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nama folder"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nama baharu"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Pratonton fail <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Semak imbas fail dalam apl lain"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Awanama"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Benarkan akses kepada \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Benarkan akses kepada \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" pada \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Aliran ini membenarkan \"<xliff:g id="APPNAME">%1$s</xliff:g>\" mendapat akses penuh kepada semua fail yang disimpan di bawah lokasi ini pada masa ini dan sebarang kandungan masa hadapan yang disimpan di sini."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Cari dalam telefon ini"</string>
 </resources>
diff --git a/res/values-my/config.xml b/res/values-my/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-my/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index b0d66e9..ea3b658 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"မျှဝေပါ"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ဖျက်ပါ"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"အားလုံးကို ရွေးပါ"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ရွေးရန်"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"အောက်ပါအရ စီရန်…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"ဤနေရာသို့ ကူးထည့်ပါ…"</string>
     <string name="menu_move" msgid="2310760789561129882">"အောက်ပါနေရာသို့ ရွှေ့ပါ…"</string>
     <string name="menu_compress" msgid="37539111904724188">"ချုံ့ရန်"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"အမျိုးအစား"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"အရွယ်အစား"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"မွမ်းမံပြီး"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ဖိုင်အမည် (A မှ Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"အမျိုးအစား (A မှ Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"အရွယ်အစား (အသေးဆုံးမှစ)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"မွမ်းမံချိန် (အဟောင်း)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ဖိုင်အမည် (Z မှ A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"အမျိုးအစား (Z မှ A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"အရွယ်အစား (အကြီးဆုံးမှစ)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"မွမ်းမံချိန် (အသစ်မှစ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"စီရန်"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> အလိုက် စီထားသည်"</string>
     <string name="directory_items" msgid="6645621978998614003">"ပစ္စည်းအရေအတွက်"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ငယ်စဉ်ကြီးလိုက်"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ကြီးစဉ်ငယ်လိုက်"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ပင်မဖိုင်တွဲများကို ပြပါ"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ပင်မဖိုင်တွဲများကို ဖျောက်ပါ"</string>
     <string name="save_error" msgid="8631128801982095782">"စာဖိုင်ကို သိမ်း၍မရခဲ့ပါ"</string>
@@ -79,7 +92,7 @@
     <string name="root_type_shortcut" msgid="6059343175525442279">"အမြန်နည်းများ"</string>
     <string name="root_type_device" msgid="1713604128005476585">"စက်ပစ္စည်းများ"</string>
     <string name="root_type_apps" msgid="8646073235029886342">"နောက်ထပ်အက်ပ်များ"</string>
-    <string name="empty" msgid="5300254272613103004">"ဘာမှ မရှိပါ"</string>
+    <string name="empty" msgid="5300254272613103004">"ဘာမျှ မရှိပါ"</string>
     <string name="no_results" msgid="2371026325236359209">"%1$s တွင် ကိုက်ညီသည့်အရာ မရှိပါ"</string>
     <string name="toast_no_application" msgid="7555319548595113121">"ဖိုင်ကို ဖွင့်၍မရပါ"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"မှတ်တမ်းဟောင်းထဲမှ ဖိုင်များကို ဖွင့်၍မရပါ"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">ဖိုင်<xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင်ကို ဖျက်နေသည်။</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"တစ်ဆင့်နောက်ပြန်ပါ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"မိတ္တူကူးရန် ပြင်ဆင်နေသည်…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"ချုံ့ရန် ပြင်ဆင်နေသည်…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"ထုတ်ယူရန် ပြင်ဆင်နေသည်…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ရွှေ့ရန် ပြင်ဆင်နေသည်…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ဖျက်ရန် ပြင်ဆင်နေသည်…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"အသင့်ပြင်နေပါသည်..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"အသင့်ပြင်နေပါသည်..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"အသင့်ပြင်နေပါသည်..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"အသင့်ပြင်နေပါသည်..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"အသင့်ပြင်နေပါသည်..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">ဖိုင်<xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်ကို မိတ္တူကူး၍ မရပါ</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> အား <xliff:g id="STORAGE"><i>^3</i></xliff:g> ရှိ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ဖိုင်လမ်းညွှန်ကို အသုံးပြုခွင့်ပေးမှာလား။"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> အား <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ဖိုင်လမ်းညွှန်ကို အသုံးပြုခွင့်ပေးမှာလား။"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> အား <xliff:g id="STORAGE"><i>^2</i></xliff:g> ရှိ ဓာတ်ပုံများနှင့် ဗီဒီယိုများအပါအဝင် သင့်ဒေတာများကို အသုံးပြုခွင့်ပေးမှာလား။"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"နောက်ထပ်မမေးပါနှင့်"</string>
     <string name="allow" msgid="1275746941353040309">"ခွင့်ပြုရန်"</string>
     <string name="deny" msgid="5127201668078153379">"ငြင်းပယ်ရန်"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"မှတ်တမ်းဟောင်း<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ကို အစားထိုးလိုပါသလား။"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"နောက်ခံတွင် ဆက်လုပ်ရန်"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ခု ရွေးချယ်ထားသည်</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ခု ရွေးချယ်ထားသည်</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ဖုန်းပေါ်ရှိ လတ်တလောဖိုင်များ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ဖုန်းပေါ်ရှိ ဖိုင်များ"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ဖုန်းပေါ်ရှိ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> ပေါ်ရှိ ဖိုင်များ"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> မှ ဖိုင်များ"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> မှ ဖိုင်များ"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ဖုန်းပေါ်ရှိ လတ်တလောပုံများ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ဖုန်းပေါ်ရှိ ပုံများ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> ပေါ်ရှိ ပုံများ"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> မှ ပုံများ"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> မှ ပုံများ"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ပုံများ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"အသံ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ဗီဒီယိုများ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"မှတ်တမ်းများ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ဖိုင်တွဲအမည်"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"အမည်အသစ်"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ဖိုင်ကို အစမ်းကြည့်ရန်"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"အခြားအက်ပ်များတွင် ဖိုင်များကို ဖွင့်ကြည့်ပါ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"အမည်မသိ"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" အသုံးပြုခွင့်ပေးရန်"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" တွင် \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ကို အသုံးပြုခွင့်ပေးမလား။"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"၎င်းက ဤတည်နေရာတွင် လက်ရှိသိမ်းထားသည့် ဖိုင်အားလုံးနှင့် နောင်ဤနေရာတွင် သိမ်းမည့် အကြောင်းအရာများသို့ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ကို အသုံးပြုခွင့် အပြည့်ပေးပါမည်။"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ဤဖုန်းကို ရှာရန်"</string>
 </resources>
diff --git a/res/values-nb/config.xml b/res/values-nb/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-nb/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 106371b..53a3084 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Del"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Slett"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Velg alle"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Velg"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortér etter"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiér til"</string>
     <string name="menu_move" msgid="2310760789561129882">"Flytt til"</string>
     <string name="menu_compress" msgid="37539111904724188">"Komprimer"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Størrelse"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Endret"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Filnavn (A til Å)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A til Å)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Størrelse (minst først)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modifisert (eldst først)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Filnavn (Å til A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Å til A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Størrelse (størst først)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modifisert (nyest først)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortér etter"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sortert etter <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Antall elementer"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stigende"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Synkende"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Åpne <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Vis røtter"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Skjul røtter"</string>
     <string name="save_error" msgid="8631128801982095782">"Kunne ikke lagre dokumentet"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Sletter <xliff:g id="COUNT_0">%1$d</xliff:g> element.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Angre"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Forbereder kopiering …"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Forbereder komprimering …"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Forbereder utpakking …"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Forbereder flytting …"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Forbereder sletting …"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Forbereder …"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Forbereder …"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Forbereder …"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Forbereder …"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Forbereder …"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Kunne ikke kopiere <xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til dataene dine – inkludert bilder og videoer – på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ikke spør igjen"</string>
     <string name="allow" msgid="1275746941353040309">"Tillat"</string>
     <string name="deny" msgid="5127201668078153379">"Avvis"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arkiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Vil du overskrive <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Fortsett i bakgrunnen"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> er valgt</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nylige filer på telefonen"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Filer på telefonen"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> på telefonen"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Filer på <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Filer fra <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Filer fra <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nylige bilder på telefonen"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Bilder på telefonen"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Bilder på <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Bilder fra <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Bilder fra <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Bilder"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Lyd"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videoer"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenter"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Mappenavn"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nytt navn"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Forhåndsvis filen <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Bla gjennom filer i andre apper"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonym"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Gi tilgang til «<xliff:g id="DIRECTORY">%1$s</xliff:g>»"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Vil du gi tilgang til «<xliff:g id="DIRECTORY">%1$s</xliff:g>» på «<xliff:g id="ROOT">%2$s</xliff:g>»?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"«<xliff:g id="APPNAME">%1$s</xliff:g>» får full tilgang til alle filer som er lagret på dette stedet, og alt fremtidig innhold som lagres her."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Søk på denne telefonen"</string>
 </resources>
diff --git a/res/values-ne/config.xml b/res/values-ne/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ne/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index cada88e..70821dd 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"साझेदारी गर्नुहोस्"</string>
     <string name="menu_delete" msgid="1022254131543256626">"मेट्नुहोस्"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"सबैलाई चयन गर्नुहोस्"</string>
+    <string name="menu_select" msgid="1366061076507142387">"चयन गर्नुहोस्"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"यसअनुसार क्रमबद्ध गर्नु..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"यसमा प्रतिलिपि बनाउनु…"</string>
     <string name="menu_move" msgid="2310760789561129882">"निम्नमा सार्नुहोस्…"</string>
     <string name="menu_compress" msgid="37539111904724188">"कम्प्रेस गर्नुहोस्"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"परिमार्जित"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"फाइलको नाम (क देखि ज्ञ)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"प्रकार (क देखि ज्ञ)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"आकार (सबैभन्दा सानो पहिले)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"परिमार्जित गरियो (सबैभन्दा पुरानो पहिले)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"फाइलको नाम (ज्ञ देखि क)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"प्रकार (ज्ञ देखि क)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"आकार (सबैभन्दा ठूलो पहिले)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"परिमार्जित गरियो (सबभन्दा नयाँ पहिलो)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"यसअनुसार क्रमबद्ध गर्नुहोस्"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> द्वारा क्रमबद्ध गरियो"</string>
     <string name="directory_items" msgid="6645621978998614003">"वस्तुहरूको संख्या"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"बढ्दो क्रम"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"घट्दो क्रम"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> खोल्नुहोस्"</string>
     <string name="drawer_open" msgid="8071673398187261741">"मूल ठाउँहरू देखाउनुहोस्"</string>
     <string name="drawer_close" msgid="4263880768630848848">"मूल ठाउँहरू लुकाउनुहोस्"</string>
     <string name="save_error" msgid="8631128801982095782">"कागजातलाई सुरक्षित गर्न सकिएन"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> वस्तु मेटाउँदै।</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"अनडू गर्नुहोस्"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"प्रतिलिपि बनाउने तयारी गर्दै…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"कम्प्रेस गर्ने तयारी गर्दै…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"एक्स्ट्र्याक्ट गर्ने तयारी गर्दै…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"सार्ने तयारी गर्दै…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"मेट्ने तयारी गर्दै…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"तयार पार्दै..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"तयार पार्दै..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"तयार पार्दै..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"तयार पार्दै..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"तयार पार्दै..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> वस्तुहरूलाई प्रतिलिपि गर्न सकिएन</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^3</i></xliff:g> मा रहेको <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामाथि पहुँच राख्न दिने हो?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामाथि पहुँच राख्न दिने हो?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^2</i></xliff:g> मा भएका तस्बिर र भिडियोहरू लगायत तपाईँको डेटामाथि पहुँच राख्न दिने हो?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"फेरि नसोध्नुहोस्"</string>
     <string name="allow" msgid="1275746941353040309">"अनुमति दिनुहोस्"</string>
     <string name="deny" msgid="5127201668078153379">"अस्वीकार गर्नुहोस्"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"अभिलेख राख्नुहोस्<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> को अधिलेखन गर्ने हो?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"पृष्ठभूमिमा जारी राख्नुहोस्"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयन गरियो</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> चयन गरियो</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"फोनमा रहेका हालसालैका फाइलहरू"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"फोनमा रहेका फाइलहरू"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"फोनमा रहेका <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> मा रहेका फाइलहरू"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> का फाइलहरू"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> का फाइलहरू"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"फोनमा रहेका हालसालैका छविहरू"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"फोनमा रहेका छविहरू"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> मा रहेका छविहरू"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> का छविहरू"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> का छविहरू"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"छविहरू"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"अडियो"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"भिडियोहरू"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"कागजातहरू"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"फोल्डरको नाम"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"नयाँ नाम"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> फाइलको पूर्वावलोकन गर्नुहोस्‌"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"अन्य अनुप्रयोगहरूमा फाइलहरू ब्राउज गर्नुहोस्‌"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"अज्ञात"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" माथि पहुँच राख्न दिनुहोस्"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" मा रहेको \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" माथि पहुँच राख्न दिने हो?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"यस कार्यले \"<xliff:g id="APPNAME">%1$s</xliff:g>\" लाई यो स्थानमा हाल भण्डारण गरिएका सबै फाइल र भविष्यमा भण्डारण गरिने जुनसुकै सामग्रीमाथि पूर्ण रूपमा पहुँच राख्न दिने छ।"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"यो फोनमा खोज्नुहोस्"</string>
 </resources>
diff --git a/minimal/res/values/drawables.xml b/res/values-night/colors.xml
similarity index 64%
copy from minimal/res/values/drawables.xml
copy to res/values-night/colors.xml
index 2e5e77d..f358b02 100644
--- a/minimal/res/values/drawables.xml
+++ b/res/values-night/colors.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,8 +13,12 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <resources>
-    <item name="app_icon" type="drawable">@mipmap/ic_app_icon</item>
-    <item name="launcher_icon" type="drawable">@mipmap/ic_app_icon</item>
+    <color name="app_background_color">#202124</color>
+    <color name="background_floating">#3C4043</color>
+    <color name="nav_bar_translucent">#52000000</color>
+
+    <color name="primary">#8AB4F8</color>
+    <color name="secondary">#3D8AB4F8</color>
+    <color name="hairline">#5F6368</color>
 </resources>
diff --git a/res/values-night/themes.xml b/res/values-night/themes.xml
new file mode 100644
index 0000000..af2d4b3
--- /dev/null
+++ b/res/values-night/themes.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="DocumentsTheme" parent="@android:style/Theme.DeviceDefault.DocumentsUI">
+
+        <!-- Toolbar -->
+        <item name="android:actionModeBackground">?android:attr/colorBackground</item>
+        <item name="android:actionBarSize">@dimen/action_bar_size</item>
+
+        <!-- Color section -->
+        <item name="android:colorAccent">@color/primary</item>
+        <item name="android:colorBackground">@color/app_background_color</item>
+        <item name="android:colorBackgroundFloating">@color/background_floating</item>
+        <item name="android:colorControlHighlight">@color/ripple_material_dark</item>
+        <item name="android:colorControlActivated">@color/primary</item>
+        <item name="android:colorPrimary">@color/primary</item>
+        <item name="android:colorSecondary">@color/secondary</item>
+        <item name="android:strokeColor">@color/hairline</item>
+
+        <!-- System | Widget section -->
+        <item name="android:listDivider">@drawable/list_divider</item>
+        <item name="android:statusBarColor">?android:attr/colorBackground</item>
+        <item name="android:windowBackground">?android:attr/colorBackground</item>
+        <item name="android:windowLightStatusBar">false</item>
+        <item name="android:windowLightNavigationBar">false</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+
+    </style>
+</resources>
diff --git a/res/values-nl/config.xml b/res/values-nl/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-nl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 6b864f9..7028c05 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Delen"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Verwijderen"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Alles selecteren"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Selecteren"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sorteren op…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiëren naar…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Verplaatsen naar…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimeren"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Type"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Grootte"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Aangepast"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Bestandsnaam (A - Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Type (A - Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Grootte (kleinste eerst)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Aangepast (oudste eerst)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Bestandsnaam (Z - A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Type (Z - A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Grootte (grootste eerst)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Aangepast (nieuwste eerst)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sorteren op"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Gesorteerd op <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Aantal items"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Oplopend"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Aflopend"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> openen"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Roots weergeven"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Roots verbergen"</string>
     <string name="save_error" msgid="8631128801982095782">"Kan document niet opslaan"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item verwijderen.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Ongedaan maken"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopiëren voorbereiden…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Comprimeren voorbereiden…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Uitpakken voorbereiden…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Verplaatsen voorbereiden…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Verwijderen voorbereiden…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Voorbereiden..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Voorbereiden..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Voorbereiden..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Voorbereiden..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Voorbereiden..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> items niet kopiëren</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot je gegevens, waaronder foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Niet meer vragen"</string>
     <string name="allow" msgid="1275746941353040309">"Toestaan"</string>
     <string name="deny" msgid="5127201668078153379">"Weigeren"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archief<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> overschrijven?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Doorgaan op de achtergrond"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> geselecteerd</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> geselecteerd</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Recente bestanden op telefoon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Bestanden op telefoon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> op telefoon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Bestanden op <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Bestanden van <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Bestanden van <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Recente afbeeldingen op telefoon"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Afbeeldingen op telefoon"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Afbeeldingen op <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Afbeeldingen van <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Afbeeldingen van <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Afbeeldingen"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video\'s"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documenten"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Mapnaam"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nieuwe naam"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Voorbeeld van het bestand <xliff:g id="FILENAME">%1$s</xliff:g> bekijken"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Door bestanden browsen in andere apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anoniem"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Toegang tot \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\' toestaan"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Toegang tot \'<xliff:g id="DIRECTORY">%1$s</xliff:g>\' toestaan op \'<xliff:g id="ROOT">%2$s</xliff:g>\'?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"\'<xliff:g id="APPNAME">%1$s</xliff:g>\' krijgt volledige toegang tot alle bestanden die op deze locatie zijn opgeslagen en daar in de toekomst worden opgeslagen."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Deze telefoon doorzoeken"</string>
 </resources>
diff --git a/res/values-or/inspector_strings.xml b/res/values-or/inspector_strings.xml
new file mode 100644
index 0000000..0e53ff5
--- /dev/null
+++ b/res/values-or/inspector_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="inspector_title" msgid="1924760928091740238">"ସୂଚନା"</string>
+    <string name="inspector_load_error" msgid="7522190243413249291">"ଫାଇଲ୍‍ ସୂଚନା ଲୋଡ୍‍ କରିହେଲା ନାହିଁ"</string>
+    <string name="inspector_debug_section" msgid="2576052661505700421">"ଡିବଗ୍‍ ସୂଚନା (କେବଳ ଡିଭାଇସ୍‍)"</string>
+    <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"ମୂଳ ମେଟାଡାଟା: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
+    <string name="inspector_metadata_section" msgid="6077622515328240575">"ମିଡିଆ ବିବରଣୀ"</string>
+    <string name="handler_app_file_opens_with" msgid="5272329600389613550">"ଏହି ପ୍ରକାରର ଫାଇଲ୍‍ ଏଥିରେ ଖୋଲେ"</string>
+    <string name="handler_app_belongs_to" msgid="5444507329303253553">"ଏହି ଫାଇଲ୍‌କୁ ଦେଇଛନ୍ତି"</string>
+    <string name="handler_app_not_selected" msgid="1294439257183908786">"ଚୟନ କରାଯାଇନାହିଁ"</string>
+    <string name="handler_app_unknown" msgid="5911661530593229287">"ଅଜଣା"</string>
+    <string name="metadata_dimensions" msgid="6112907724016659801">"ମାପ"</string>
+    <string name="metadata_dimensions_format" msgid="6138765871412005962">"<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g> - <xliff:g id="MEGAPIXELS">%3$,.1f</xliff:g>MP"</string>
+    <string name="metadata_coordinates" msgid="6897383227370702734">"ନିର୍ଦ୍ଦେଶାଙ୍କ"</string>
+    <string name="metadata_coordinates_format" msgid="1402724596764547761">"<xliff:g id="LATITUDE">%1$,.3f</xliff:g>, <xliff:g id="LONGITUDE">%2$,.3f</xliff:g>"</string>
+    <string name="metadata_altitude" msgid="8063792127436794294">"ଉଚ୍ଚତା"</string>
+    <string name="metadata_camera" msgid="2363009732801281319">"କ୍ୟାମେରା"</string>
+    <string name="metadata_camera_format" msgid="1494489751904311612">"<xliff:g id="MAKE">%1$s</xliff:g> <xliff:g id="MODEL">%2$s</xliff:g>"</string>
+    <string name="metadata_aperture" msgid="6538741952698935357">"ଆପାର୍ଚର୍‍"</string>
+    <string name="metadata_shutter_speed" msgid="8204739885103326131">"ଶଟର୍‌ ସ୍ପୀଡ୍‌"</string>
+    <string name="metadata_duration" msgid="3115494422055472715">"ଅବଧି"</string>
+    <string name="metadata_date_time" msgid="1090351199248114406">"ଫଟୋ ଉଠାଯାଇଥିବା ସମୟ"</string>
+    <string name="metadata_focal_length" msgid="3440735161407699893">"ଫୋକସ୍‌ ଦୈର୍ଘ୍ୟ"</string>
+    <string name="metadata_focal_format" msgid="8542211707962355623">"<xliff:g id="LENGTH">%1$.2f </xliff:g>ମିମି"</string>
+    <string name="metadata_iso_speed_ratings" msgid="1699781252899759058">"ISO ସମତୁଲ୍ୟ"</string>
+    <string name="metadata_iso_format" msgid="4153285204012694861">"ISO <xliff:g id="ISO_SPEED">%1$d</xliff:g>"</string>
+    <string name="metadata_artist" msgid="8972421485694988540">"କଳାକାର"</string>
+    <string name="metadata_composer" msgid="4696926808308256056">"କମ୍ପୋଜର୍‍"</string>
+    <string name="metadata_album" msgid="1661699531214720236">"ଆଲବମ୍"</string>
+    <string name="metadata_address" msgid="1849921023707744640">"ଲୋକେଶନ୍‌"</string>
+    <string name="debug_stream_types" msgid="2088565280360139333">"ଷ୍ଟ୍ରୀମ୍‍ର ପ୍ରକାର"</string>
+    <string name="debug_raw_size" msgid="7487139640175650185">"ମୂଳ ଆକାର (ବାଇଟ୍ସ)"</string>
+</resources>
diff --git a/res/values-or/mimes.xml b/res/values-or/mimes.xml
new file mode 100644
index 0000000..a881620
--- /dev/null
+++ b/res/values-or/mimes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="generic_extention_file_type" msgid="5947398320635880291">"<xliff:g id="EXTENSION">%1$s</xliff:g> ଫାଇଲ୍‍"</string>
+    <string name="generic_file_type" msgid="1415477154743494280">"ଫାଇଲ୍"</string>
+    <string name="image_file_type" msgid="3011633523704887793">"ଇମେଜ୍‍"</string>
+    <string name="image_extension_file_type" msgid="992617216367594851">"<xliff:g id="FILETYPE">%1$s</xliff:g> ଇମେଜ୍‍"</string>
+    <string name="audio_file_type" msgid="3790525543519624632">"ଅଡିଓ"</string>
+    <string name="audio_extension_file_type" msgid="6334293531796491314">"<xliff:g id="FILETYPE">%1$s</xliff:g> ଅଡିଓ"</string>
+    <string name="video_file_type" msgid="7290473366042482095">"ଭିଡିଓ"</string>
+    <string name="video_extension_file_type" msgid="6352763029831291433">"<xliff:g id="FILETYPE">%1$s</xliff:g> ଭିଡିଓ"</string>
+    <string name="archive_file_type" msgid="1463432996680398798">"<xliff:g id="FILETYPE">%1$s</xliff:g> ଆର୍କାଇଭ୍‌"</string>
+    <string name="apk_file_type" msgid="6004275470389462277">"Android ଆପ୍ଲିକେଶନ୍‌"</string>
+    <string name="txt_file_type" msgid="4677767777860724696">"କେବଳ ଟେକ୍ସଟ୍‌"</string>
+    <string name="html_file_type" msgid="2034229603117527970">"HTML ଡକୁମେଣ୍ଟ"</string>
+    <string name="pdf_file_type" msgid="3382260303795039988">"PDF ଡକୁମେଣ୍ଟ"</string>
+    <string name="word_file_type" msgid="2366349268129894972">"Word ଡକୁମେଣ୍ଟ"</string>
+    <string name="ppt_file_type" msgid="2570841599899893925">"ପାୱାର୍‌ପଏଣ୍ଟ ପ୍ରେଜେଣ୍ଟେଶନ୍‌"</string>
+    <string name="excel_file_type" msgid="8363932635044575463">"Excel ସ୍ପ୍ରେଡଶୀଟ୍‍"</string>
+    <string name="gdoc_file_type" msgid="242328101061228382">"Google ଡକୁମେଣ୍ଟ"</string>
+    <string name="gsheet_file_type" msgid="8055591929133067952">"Google ସ୍ପ୍ରେଡଶୀଟ୍‌"</string>
+    <string name="gslides_file_type" msgid="8359750985956690177">"Google ପ୍ରେଜେଣ୍ଟେଶନ୍‌"</string>
+    <string name="gdraw_file_type" msgid="655688091676820371">"Google ଡ୍ରଇଙ୍ଗ"</string>
+    <string name="gtable_file_type" msgid="7332773878374650335">"Google ଟେବଲ୍‌"</string>
+    <string name="gform_file_type" msgid="4803176103746107611">"Google ଫର୍ମ"</string>
+    <string name="gmap_file_type" msgid="6684180781808007016">"Google ମ୍ୟାପ୍‌"</string>
+    <string name="gsite_file_type" msgid="3742812051249149526">"Google ସାଇଟ୍"</string>
+    <string name="directory_type" msgid="2702987727566226354">"ଫୋଲ୍ଡର୍"</string>
+</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
new file mode 100644
index 0000000..554b6fd
--- /dev/null
+++ b/res/values-or/strings.xml
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="files_label" msgid="771781190045103748">"ଫାଇଲ୍‍"</string>
+    <string name="downloads_label" msgid="5462789470049501103">"ଡାଉନଲୋଡ୍‌"</string>
+    <!-- no translation found for app_label (8089292432455111409) -->
+    <skip />
+    <!-- no translation found for launcher_label (799410258349837668) -->
+    <skip />
+    <string name="title_open" msgid="3165686459158020921">"ଏଥିରୁ ଖୋଲନ୍ତୁ"</string>
+    <string name="title_save" msgid="4384490653102710025">"ଏଥିରେ ସେଭ୍‍ କରନ୍ତୁ"</string>
+    <string name="menu_create_dir" msgid="2413624798689091042">"ନୂଆ ଫୋଲ୍ଡର୍‌"</string>
+    <string name="menu_grid" msgid="1453636521731880680">"ଗ୍ରୀଡ୍‍ ଭ୍ୟୁ"</string>
+    <string name="menu_list" msgid="6714267452146410402">"ତାଲିକା ଭ୍ୟୁ"</string>
+    <string name="menu_search" msgid="1876699106790719849">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+    <string name="menu_settings" msgid="6520844520117939047">"ଷ୍ଟୋରେଜ୍‌ ସେଟିଙ୍ଗ"</string>
+    <string name="menu_open" msgid="9092138100049759315">"ଖୋଲନ୍ତୁ"</string>
+    <string name="menu_open_with" msgid="5507647065467520229">"ଏଥିରେ ଖୋଲନ୍ତୁ"</string>
+    <string name="menu_open_in_new_window" msgid="6686563636123311276">"ନୂଆ ୱିଣ୍ଡୋରେ ଖୋଲନ୍ତୁ"</string>
+    <string name="menu_save" msgid="5195367497138965168">"ସେଭ୍‌ କରନ୍ତୁ"</string>
+    <string name="menu_share" msgid="4307140947108068356">"ଶେୟାର୍‍ କରନ୍ତୁ"</string>
+    <string name="menu_delete" msgid="1022254131543256626">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="menu_select_all" msgid="7600576812185570403">"ସବୁ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ଚୟନ କରନ୍ତୁ"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ଏହି ଅନୁସାରେ ସଜାନ୍ତୁ..."</string>
+    <string name="menu_copy" msgid="7404820171352314754">"ଏଥିକୁ କପୀ କରନ୍ତୁ…"</string>
+    <string name="menu_move" msgid="2310760789561129882">"ଏଥିକୁ ନିଅନ୍ତୁ…"</string>
+    <string name="menu_compress" msgid="37539111904724188">"ଛୋଟ କରନ୍ତୁ"</string>
+    <string name="menu_extract" msgid="8171946945982532262">"ଏଠାକୁ ଏକ୍ସଟ୍ରାକ୍ଟ କରନ୍ତୁ…"</string>
+    <string name="menu_rename" msgid="1883113442688817554">"ନାମ ବଦଳାନ୍ତୁ"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"ସୂଚନା ପାଆନ୍ତୁ"</string>
+    <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g>ରେ ଦେଖନ୍ତୁ"</string>
+    <string name="menu_new_window" msgid="2947837751796109126">"ନୂଆ ୱିଣ୍ଡୋ"</string>
+    <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"କଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"କପୀ କରନ୍ତୁ"</string>
+    <string name="menu_paste_from_clipboard" msgid="360947260414135827">"ପେଷ୍ଟ କରନ୍ତୁ"</string>
+    <string name="menu_paste_into_folder" msgid="8000644546983240101">"ଫୋଲ୍ଡର୍‌ରେ ପେଷ୍ଟ କରନ୍ତୁ"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"ଇଣ୍ଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌କୁ ଦେଖାନ୍ତୁ"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"ଇଣ୍ଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌କୁ ଲୁଚାନ୍ତୁ"</string>
+    <string name="button_select" msgid="240863497069321364">"ଚୟନ କରନ୍ତୁ"</string>
+    <string name="button_copy" msgid="8219059853840996027">"କପୀ କରନ୍ତୁ"</string>
+    <string name="button_compress" msgid="8951561310857223966">"ଛୋଟ କରନ୍ତୁ"</string>
+    <string name="button_extract" msgid="1038674453689912247">"ଏକ୍ସଟ୍ରାକ୍ଟ କରନ୍ତୁ"</string>
+    <string name="button_move" msgid="8596460499325291272">"ନେଇଯାଆନ୍ତୁ"</string>
+    <string name="button_dismiss" msgid="7235249361023803349">"ଖାରଜ କରନ୍ତୁ"</string>
+    <string name="button_retry" msgid="4011461781916631389">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="button_clear" msgid="5412304437764369441">"ଖାଲି କରନ୍ତୁ"</string>
+    <string name="button_show_provider" msgid="6905880493806292753">"ପ୍ରଦାତା ସର୍ଭିସ୍‌ରେ ଦେଖାନ୍ତୁ"</string>
+    <string name="not_sorted" msgid="7813496644889115530">"କ୍ରମବଦ୍ଧ କରାଯାଇନାହିଁ"</string>
+    <string name="sort_dimension_name" msgid="6325591541414177579">"ନାମ"</string>
+    <string name="sort_dimension_summary" msgid="7724534446881397860">"ସାରାଂଶ"</string>
+    <string name="sort_dimension_file_type" msgid="5779709622922085381">"ପ୍ରକାର"</string>
+    <string name="sort_dimension_size" msgid="2190547351159472884">"ଆକାର"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"ଗତଥର ସଂଶୋଧିତ"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ଫାଇଲ୍‍ ନାମ (A ରୁ Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ଟାଇପ୍‌ (A ରୁ Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ଆକର (ପ୍ରଥମେ ଛୋଟ)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ସଂଶୋଧିତ (ପ୍ରଥମେ ପୁରୁଣା)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ଫାଇଲ୍‍ ନାମ (Z ରୁ A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ଟାଇପ୍‍ (Z ରୁ A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ଆକାର (ପ୍ରଥମେ ବୃହତ)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ସଂଶୋଧିତ (ପ୍ରଥମେ ନୂଆ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ଏହି ଅନୁସାରେ ସଜାନ୍ତୁ"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> ଦ୍ବାରା ସର୍ଟ ହୋଇଛି"</string>
+    <string name="directory_items" msgid="6645621978998614003">"ଆଇଟମ୍‌ଗୁଡ଼ିକର ସଂଖ୍ୟା"</string>
+    <string name="sort_direction_ascending" msgid="5882787683763248102">"ସାନରୁ ବଡ଼ କ୍ରମରେ"</string>
+    <string name="sort_direction_descending" msgid="1729187589765894076">"ବଡ଼ରୁ ସାନ କ୍ରମରେ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ଖୋଲନ୍ତୁ।"</string>
+    <string name="drawer_open" msgid="8071673398187261741">"ରୁଟ୍‍ ଦେଖାନ୍ତୁ"</string>
+    <string name="drawer_close" msgid="4263880768630848848">"ରୁଟ୍‍ ଲୁଚାନ୍ତୁ"</string>
+    <string name="save_error" msgid="8631128801982095782">"ଡକୁମେଣ୍ଟକୁ ସେଭ୍‍ କରିପାରିଲା ନାହିଁ"</string>
+    <string name="create_error" msgid="3092144450044861994">"ଫୋଲ୍ଡର୍‍ ତିଆରି କରିହେଲା ନାହିଁ"</string>
+    <string name="query_error" msgid="6625421453613879336">"ଏହି ସମୟରେ କଣ୍ଟେଣ୍ଟ ଲୋଡ୍‍ କରିପାରିବ ନାହିଁ"</string>
+    <string name="root_recent" msgid="1080156975424341623">"କିଛି ସମୟ ପୂର୍ବରୁ"</string>
+    <string name="root_available_bytes" msgid="8269870862691408864">"<xliff:g id="SIZE">%1$s</xliff:g> ଖାଲି ଅଛି"</string>
+    <string name="root_type_service" msgid="6521366147466512289">"ଷ୍ଟୋରେଜ୍‍ ସେବା"</string>
+    <string name="root_type_shortcut" msgid="6059343175525442279">"ଶର୍ଟକଟ୍‍"</string>
+    <string name="root_type_device" msgid="1713604128005476585">"ଡିଭାଇସ୍‌"</string>
+    <string name="root_type_apps" msgid="8646073235029886342">"ଅଧିକ ଆପ୍‍"</string>
+    <string name="empty" msgid="5300254272613103004">"କୌଣସି ଆଇଟମ୍ ନାହିଁ"</string>
+    <string name="no_results" msgid="2371026325236359209">"%1$sରେ କିଛି ମେଳ ହେଉନାହିଁ"</string>
+    <string name="toast_no_application" msgid="7555319548595113121">"ଫାଇଲ୍‍ ଖୋଲିହେବ ନାହିଁ"</string>
+    <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"ସଂଗ୍ରହରେ ଥିବା ଫାଇଲ୍‍ ଖୋଲିପାରିବ ନାହିଁ"</string>
+    <string name="toast_failed_delete" msgid="3453846588205817591">"କିଛି ଡକୁମେଣ୍ଟ ଡିଲିଟ୍‍ କରିହେବ ନାହିଁ"</string>
+    <string name="share_via" msgid="8725082736005677161">"ଏହା ମାଧ୍ୟମରେ ଶେୟାର୍‌ କରନ୍ତୁ"</string>
+    <string name="copy_notification_title" msgid="52256435625098456">"ଫାଇଲ୍‌ଗୁଡ଼ିକ କପୀ କରାଯାଉଛି"</string>
+    <string name="compress_notification_title" msgid="6830195148113751021">"ଫାଇଲ୍‍ ଛୋଟ କରାଯାଉଛି"</string>
+    <string name="extract_notification_title" msgid="5067393961754430469">"ଫାଇଲ୍‍ ଏକ୍ସଟ୍ରାକ୍ଟ କରିବା"</string>
+    <string name="move_notification_title" msgid="3173424987049347605">"ଫାଇଲ୍‌ଗୁଡ଼ିକ ନିଆଯାଉଛି"</string>
+    <string name="delete_notification_title" msgid="2512757431856830792">"ଫାଇଲ୍‍ ଡିଲିଟ୍‌ କରାଯାଉଛି"</string>
+    <string name="copy_remaining" msgid="5390517377265177727">"<xliff:g id="DURATION">%s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍ କପୀ କରାଯାଉଛି।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍ କପୀ କରାଯାଉଛି।</item>
+    </plurals>
+    <plurals name="compress_begin" formatted="false" msgid="3534158317098678895">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଛୋଟ କରାଯାଉଛି।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଛୋଟ କରାଯାଉଛି।</item>
+    </plurals>
+    <plurals name="extract_begin" formatted="false" msgid="1006380679562903749">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଏକ୍ସଟ୍ରାକ୍ଟ କରାଯାଉଛି।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଏକ୍ସଟ୍ରାକ୍ଟ କରାଯାଉଛି।</item>
+    </plurals>
+    <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ନିଆଯାଉଛି।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ନିଆଯାଉଛି।</item>
+    </plurals>
+    <plurals name="deleting" formatted="false" msgid="1729138001178158901">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ଡିଲିଟ୍‍ କରାଯାଉଛି।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ଡିଲିଟ୍‍ କରାଯାଉଛି।</item>
+    </plurals>
+    <string name="undo" msgid="2902438994196400565">"ପୂର୍ବପରି କରନ୍ତୁ"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"ପ୍ରସ୍ତୁତ କରାଯାଉଛି…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"ପ୍ରସ୍ତୁତ କରାଯାଉଛି…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"ପ୍ରସ୍ତୁତ କରାଯାଉଛି…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"ପ୍ରସ୍ତୁତ କରାଯାଉଛି…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"ପ୍ରସ୍ତୁତ କରାଯାଉଛି…"</string>
+    <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+    <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ କପୀ କରାଯାଇପାରିଲା ନାହିଁ</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ କପୀ କରାଯାଇପାରିଲା ନାହିଁ</item>
+    </plurals>
+    <plurals name="compress_error_notification_title" formatted="false" msgid="3043630066678213644">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଛୋଟ କରାଯାଇପାରିଲା ନାହିଁ</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଛୋଟ କରାଯାଇପାରିଲା ନାହିଁ</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2185736082411854754">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ନିଆଯାଇପାରିଲା ନାହିଁ।</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ନିଆଯାଇପାରିଲା ନାହିଁ।</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7568122018481625267">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ଡିଲିଟ୍‍ କରାଯାଇପାରିଲା ନାହିଁ</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ଡିଲିଟ୍‍ କରାଯାଇପାରିଲା ନାହିଁ</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="2385563502445129570">"ବିବରଣୀ ଦେଖିବା ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
+    <string name="close" msgid="905969391788869975">"ବନ୍ଦ କରନ୍ତୁ"</string>
+    <plurals name="copy_failure_alert_content" formatted="false" msgid="5570549471912990536">
+      <item quantity="other">ଏହି ଫାଇଲ୍‍ କପୀ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ଏହି ଫାଇଲ୍‍ କପୀ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="compress_failure_alert_content" formatted="false" msgid="5760632881868842400">
+      <item quantity="other">ଏହି ଫାଇଲଗୁଡ଼ିକ ଛୋଟ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ଏହି ଫାଇଲ୍‍ ଛୋଟ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="extract_failure_alert_content" formatted="false" msgid="7572748127571720803">
+      <item quantity="other">ଏହି ଫାଇଲଗୁଡ଼ିକ ଏକ୍ସଟ୍ରାକ୍ଟ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ଏହି ଫାଇଲ୍‍ ଏକ୍ସଟ୍ରାକ୍ଟ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="move_failure_alert_content" formatted="false" msgid="2747390342670799196">
+      <item quantity="other">ଏହି ଫାଇଲଗୁଡ଼ିକ ନିଆଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ଏହି ଫାଇଲ୍‍ ନିଆଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="delete_failure_alert_content" formatted="false" msgid="6122372614839711711">
+      <item quantity="other">ଏହି ଫାଇଲଗୁଡ଼ିକ ଡିଲିଟ୍‍ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ଏହି ଫାଇଲ୍‍ ଡିଲିଟ୍‍ କରାଯାଇପାରିଲା ନାହିଁ: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="copy_converted_warning_content" formatted="false" msgid="7433742181712126588">
+      <item quantity="other">ଏହି ଫାଇଲଗୁଡ଼ିକ ଅନ୍ୟ ଫର୍ମାଟରେ ବଦଳାଗଲା: <xliff:g id="LIST_1">%1$s</xliff:g></item>
+      <item quantity="one">ଏହି ଫାଇଲ୍‍ ଅନ୍ୟ ଫର୍ମାଟରେ ବଦଳାଗଲା: <xliff:g id="LIST_0">%1$s</xliff:g></item>
+    </plurals>
+    <plurals name="clipboard_files_clipped" formatted="false" msgid="4847061634862926902">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ କ୍ଲିପ୍‌ବୋର୍ଡକୁ କପୀ କରାଗଲା</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ କ୍ଲିପ୍‌ବୋର୍ଡକୁ କପୀ କରାଗଲା</item>
+    </plurals>
+    <string name="file_operation_rejected" msgid="4301554203329008794">"ଫାଇଲ୍‍ ଅପରେସନ୍‍ ସପୋର୍ଟ କଲାନାହିଁ।"</string>
+    <string name="file_operation_error" msgid="2234357335716533795">"ଫାଇଲ୍ ଅପରେସନ୍‍ କରାଯାଇପାରିଲା ନାହିଁ"</string>
+    <string name="rename_error" msgid="6700093173508118635">"ଡକୁମେଣ୍ଟର ନାମ ବଦଳାଇବାରେ ବିଫଳ ହେଲା"</string>
+    <string name="menu_eject_root" msgid="9215040039374893613">"ବାହାର କରନ୍ତୁ"</string>
+    <string name="notification_copy_files_converted_title" msgid="6916768494891833365">"କିଛି ଫାଇଲ୍‍ ବଦଳାଯାଇଥିଲା"</string>
+    <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g>ରେ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ଡିରେକ୍ଟୋରୀକୁ <xliff:g id="APPNAME"><b>^1</b></xliff:g>ର ଆକ୍ସେସ୍‍ ମଞ୍ଜୁରୀ ଦେବେ?"</string>
+    <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ଡିରେକ୍ଟୋରୀକୁ <xliff:g id="APPNAME"><b>^1</b></xliff:g>ର ଆକ୍ସେସ୍‍ ମଞ୍ଜୁରୀ ଦେବେ?"</string>
+    <string name="open_external_dialog_root_request" msgid="6776729293982633">"ଫଟୋ ଓ ଭିଡିଓ ସମେତ <xliff:g id="STORAGE"><i>^2</i></xliff:g>ରେ, ଆପଣଙ୍କ ଡାଟାକୁ <xliff:g id="APPNAME"><b>^1</b></xliff:g>ର ଆକ୍ସେସ୍‍ ମଞ୍ଜୁରୀ ଦେବେ?"</string>
+    <string name="allow" msgid="1275746941353040309">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="deny" msgid="5127201668078153379">"ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତୁ"</string>
+    <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଚୟନିତ</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଚୟନିତ</item>
+    </plurals>
+    <plurals name="elements_dragged" formatted="false" msgid="5932571296037626279">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍</item>
+    </plurals>
+    <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ଡିଲିଟ୍‍ କରିବେ?"</string>
+    <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ଫୋଲ୍ଡର୍‍ ଓ ତାହାର କଣ୍ଟେଣ୍ଟ ଡିଲିଟ୍‍ କରିବେ?"</string>
+    <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଡିଲିଟ୍‍ କରିବେ?</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଫାଇଲ୍‍ ଡିଲିଟ୍‍ କରିବେ?</item>
+    </plurals>
+    <plurals name="delete_folders_confirmation_message" formatted="false" msgid="1028946402799686388">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଫୋଲ୍ଡର୍‍ ଓ ସେଗୁଡ଼ିକର କଣ୍ଟେଣ୍ଟ ଡିଲିଟ୍‍ କରିବେ?</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଫୋଲ୍ଡର୍‍ ଓ ତାହାର କଣ୍ଟେଣ୍ଟ ଡିଲିଟ୍‍ କରିବେ?</item>
+    </plurals>
+    <plurals name="delete_items_confirmation_message" formatted="false" msgid="7285090426511028179">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ଡିଲିଟ୍‍ କରିବେ?</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଆଇଟମ୍‍ ଡିଲିଟ୍‍ କରିବେ?</item>
+    </plurals>
+    <string name="images_shortcut_label" msgid="2545168016070493574">"ଇମେଜ୍‌"</string>
+    <string name="archive_loading_failed" msgid="7243436722828766996">"ବ୍ରାଉଜ୍‍ କରିବା ପାଇଁ ସଂଗ୍ରହ ଖୋଲିପାରିବ ନାହିଁ। ଫାଇଲ୍‍ ଖରାପ ହୋଇଯାଇଥାଇପାରେ, କିମ୍ବା ଏହାର ଫର୍ମାଟ୍ ସପୋର୍ଟ କରୁନାହିଁ।"</string>
+    <string name="name_conflict" msgid="28407269328862986">"ଏହି ନାମରେ ଗୋଟିଏ ଫାଇଲ୍‍ ପୂର୍ବରୁ ରହିଛି।"</string>
+    <string name="authentication_required" msgid="8030880723643436099">"ଏହି ଡିରେକ୍ଟୋରୀ ଦେଖିବାକୁ, <xliff:g id="NAME">%1$s</xliff:g>ରେ ସାଇନ୍‍ କରନ୍ତୁ"</string>
+    <string name="cant_display_content" msgid="8633226333229417237">"ଜଣ୍ଟେଣ୍ଟ ଦେଖାଇ ପାରିବ ନାହିଁ"</string>
+    <string name="sign_in" msgid="6253762676723505592">"ସାଇନ୍‌-ଇନ୍ କରନ୍ତୁ"</string>
+    <string name="new_archive_file_name" msgid="1604650338077249838">"ସଂଗ୍ରହ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
+    <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g>ଙ୍କୁ ବଦଳାଇବେ?"</string>
+    <string name="continue_in_background" msgid="1974214559047793331">"ବ୍ୟାକଗ୍ରାଉଣ୍ଡରେ ଜାରିରଖନ୍ତୁ"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଚୟନ କରାଯାଇଛି</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଚୟନ କରାଯାଇଛି</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ଫୋନ୍‌ରେ ଥିବା କିଛି ସମୟପୂର୍ବର ଫାଇଲ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ଫୋନ୍‌ରେ ଥିବା ଫାଇଲ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ଫୋନ୍‌ରେ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଥିବା ଫାଇଲ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>ରୁ ଫାଇଲ୍‍ଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>ରୁ ଫାଇଲ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ଫୋନ୍‌ରେ ଥିବା ବର୍ତ୍ତମାନର ଛବିଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ଫୋନ୍‌ରେ ଥିବା ଛବିଗୁଡ଼ିକ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଥିବା ଛବି"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>ରୁ ଛବି"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>ରୁ ଛବିଗୁଡ଼ିିିିକ"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ଛବି"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ଅଡିଓ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ଭିଡିଓ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ଡକ୍ୟୁମେଣ୍ଟ"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ଫୋଲ୍ଡର୍‌ ନାମ"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ନୂଆ ନାମ"</string>
+    <string name="preview_file" msgid="4056622696305432343">"ଫାଇଲ୍‍ <xliff:g id="FILENAME">%1$s</xliff:g> ପୂର୍ବାବଲୋକନ କରନ୍ତୁ"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ଅନ୍ୟ ଆପ୍ସରେ ଫାଇଲ୍‍ ବ୍ରାଉଜ୍‍ କରନ୍ତୁ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ବେନାମୀ"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"କୁ ଆକ୍ସେସ୍‌ କରିବା ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\"ରେ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"କୁ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ଏହା \"<xliff:g id="APPNAME">%1$s</xliff:g>\"କୁ ଏହି ଲୋକେସନ୍‌ରେ ଏବେ ଷ୍ଟୋର୍ ହୋଇଥିବା ଏବଂ ଏଠାରେ ଭବିଷ୍ୟତରେ ଷ୍ଟୋର୍ ହେବାକୁ ଥିବା ସମସ୍ତ ଫାଇଲ୍‌କୁ ସମ୍ପୂର୍ଣ୍ଣ ଆକ୍ସେସ୍‍‍‍‍ କରିବାକୁ ଅନୁମତି ଦେବ।"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ଏହି ଫୋନ୍‌ ଖୋଜନ୍ତୁ"</string>
+</resources>
diff --git a/res/values-pa/config.xml b/res/values-pa/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-pa/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 0a320ae..0563276 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ਮਿਟਾਓ"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"ਸਭ ਚੁਣੋ"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ਚੁਣੋ"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ਇਸ ਮੁਤਾਬਕ ਕ੍ਰਮ-ਬੱਧ ਕਰੋ..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"ਇਸ ਵਿੱਚ ਕਾਪੀ ਕਰੋ…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ਇਸ ਵਿੱਚ ਤਬਦੀਲ ਕਰੋ..."</string>
     <string name="menu_compress" msgid="37539111904724188">"ਆਕਾਰ ਛੋਟਾ ਕਰੋ"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ਕਿਸਮ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ਆਕਾਰ"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ਸੋਧਣ ਦਾ ਸਮਾਂ"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ਫ਼ਾਈਲ ਦਾ ਨਾਮ (A ਤੋਂ Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ਕਿਸਮ (A ਤੋਂ Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ਆਕਾਰ (ਸਭ ਤੋਂ ਛੋਟਾ ਪਹਿਲਾਂ)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ਸੋਧਿਆ (ਸਭ ਤੋਂ ਪੁਰਾਣੀ ਪਹਿਲਾਂ)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ਫ਼ਾਈਲ ਦਾ ਨਾਮ (Z ਤੋਂ A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ਕਿਸਮ (Z ਤੋਂ A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ਆਕਾਰ (ਸਭ ਤੋਂ ਵੱਡਾ ਪਹਿਲਾਂ)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ਸੋਧਿਆ (ਸਭ ਤੋਂ ਨਵੀਂ ਪਹਿਲਾਂ)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ਇਸ ਮੁਤਾਬਕ ਕ੍ਰਮਬੱਧ ਕਰੋ"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> ਮੁਤਾਬਕ ਕ੍ਰਮਬੱਧ ਕੀਤਾ"</string>
     <string name="directory_items" msgid="6645621978998614003">"ਆਈਟਮਾਂ ਦੀ ਗਿਣਤੀ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ਵਧਦਾ ਕ੍ਰਮ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"ਘਟਦਾ ਕ੍ਰਮ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ਨੂੰ ਖੋਲ੍ਹੋ"</string>
     <string name="drawer_open" msgid="8071673398187261741">"ਰੂਟਾਂ ਨੂੰ  ਦਿਖਾਓ"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ਰੂਟਾਂ ਨੂੰ ਲੁਕਾਓ"</string>
     <string name="save_error" msgid="8631128801982095782">"ਦਸਾਤਵੇਜ਼ ਰੱਖਿਅਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
@@ -112,11 +125,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਮਿਟਾਇਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"ਅਣਕੀਤਾ ਕਰੋ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"ਕਾਪੀ ਕਰਨ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"ਆਕਾਰ ਛੋਟਾ ਕਰਨ ਦੀ ਤਿਆਰੀ ਅਧੀਨ…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"ਐਕਸਟ੍ਰੈਕਟ ਕਰਨ ਦੀ ਤਿਆਰੀ…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ਤਬਦੀਲ ਕਰਨ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"ਮਿਟਾਉਣ ਦੀ ਤਿਆਰੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"ਤਿਆਰ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"ਤਿਆਰ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"ਤਿਆਰ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"ਤਿਆਰ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"ਤਿਆਰ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^3</i></xliff:g> \'ਤੇ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ਉੱਪਰ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ ਤੁਹਾਡੇ ਡਾਟਾ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
     <string name="allow" msgid="1275746941353040309">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
     <string name="deny" msgid="5127201668078153379">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"ਪੁਰਾਲੇਖ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> ਉੱਤੇ ਲਿਖੀਏ?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਜਾਰੀ ਰੱਖੋ"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣਿਆ ਗਿਆ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੇ ਗਏ</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ਫ਼ੋਨ \'ਤੇ ਹਾਲੀਆ ਫ਼ਾਈਲਾਂ"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ਫ਼ੋਨ \'ਤੇ ਫ਼ਾਈਲਾਂ"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ਫ਼ੋਨ \'ਤੇ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> ਵਿੱਚ ਫ਼ਾਈਲਾਂ"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> ਦੀਆਂ ਫ਼ਾਈਲਾਂ"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> ਦੀਆਂ ਫ਼ਾਈਲਾਂ"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ਫ਼ੋਨ ਵਿਚਲੇ ਹਾਲੀਆ ਚਿੱਤਰ"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ਫ਼ੋਨ ਵਿਚਲੇ ਚਿੱਤਰ"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> ਵਿਚਲੇ ਚਿੱਤਰ"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> ਤੋਂ ਚਿੱਤਰ"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> ਤੋਂ ਚਿੱਤਰ"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"ਚਿੱਤਰ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ਆਡੀਓ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ਵੀਡੀਓ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ਦਸਤਾਵੇਜ਼"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ਫੋਲਡਰ ਦਾ ਨਾਮ"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ਨਵਾਂ ਨਾਮ"</string>
+    <string name="preview_file" msgid="4056622696305432343">"ਫ਼ਾਈਲ <xliff:g id="FILENAME">%1$s</xliff:g> ਦੀ ਪੂਰਵ-ਝਲਕ ਦੇਖੋ"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ਹੋਰ ਐਪਾਂ ਵਿੱਚ ਫ਼ਾਈਲਾਂ ਬ੍ਰਾਊਜ਼ ਕਰੋ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ਗੁਮਨਾਮ"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ਫੋਲਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦਿਓ"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"ਕੀ \"<xliff:g id="ROOT">%2$s</xliff:g>\" ਦੇ \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ਫੋਲਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ਇੰਝ ਕਰਨ ਨਾਲ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ਕੋਲ ਇਸ ਟਿਕਾਣੇ ਵਿੱਚ ਸਟੋਰ ਕੀਤੀਆਂ ਸਾਰੀਆਂ ਮੌਜੂਦਾ ਫ਼ਾਈਲਾਂ ਅਤੇ ਭਵਿੱਖ ਵਿੱਚ ਇੱਥੇ ਸਟੋਰ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਸਮੱਗਰੀ ਤੱਕ ਪੂਰੀ ਪਹੁੰਚ ਹੋਵੇਗੀ।"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ਇਹ ਫ਼ੋਨ ਖੋਜੋ"</string>
 </resources>
diff --git a/res/values-pl/config.xml b/res/values-pl/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-pl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 13c3264..df3355a 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Udostępnij"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Usuń"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Zaznacz wszystko"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Wybierz"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortuj według..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiuj do…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Przenieś do…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Skompresuj"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Typ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Rozmiar"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Zmieniono"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nazwa pliku (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Typ (A–Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Rozmiar (malejąco)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Zmodyfikowane (od najstarszych)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nazwa pliku (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Typ (Z–A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Rozmiar (malejąco)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Zmodyfikowane (od najnowszych)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortuj według"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Posortowano wg: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Liczba elementów"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Rosnąco"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Malejąco"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Otwórz aplikację <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Pokaż elementy główne"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ukryj elementy główne"</string>
     <string name="save_error" msgid="8631128801982095782">"Nie udało się zapisać dokumentu"</string>
@@ -122,11 +135,11 @@
       <item quantity="one">Usuwam <xliff:g id="COUNT_0">%1$d</xliff:g> element.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Cofnij"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Przygotowuję do kopiowania…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Przygotowuję do skompresowania…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Przygotowuję do wypakowania…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Przygotowuję przenoszenie…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Przygotowuję do usunięcia…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Przygotowuję..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Przygotowuję..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Przygotowuję..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Przygotowuję..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Przygotowuję..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="few">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> elementów</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> w pamięci masowej <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Przyznać aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do Twoich danych, w tym zdjęć i filmów, zapisanych w pamięci <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Nie pytaj ponownie"</string>
     <string name="allow" msgid="1275746941353040309">"Zezwól"</string>
     <string name="deny" msgid="5127201668078153379">"Odmów"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archiwum<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Zastąpić plik <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Kontynuuj w tle"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="few">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="many">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Wybrano <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Najnowsze pliki na telefonie"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Pliki na telefonie"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> na telefonie"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Pliki na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Pliki z: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Pliki z: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Ostatnie zdjęcia na telefonie"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Zdjęcia na telefonie"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Zdjęcia na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Zdjęcia z etykietą <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Zdjęcia z: <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Obrazy"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Dźwięk"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Wideo"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenty"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nazwa folderu"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nowa nazwa"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Wyświetl podgląd pliku <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Przeglądaj pliki w innych aplikacjach"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonimowa"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Zezwalaj na dostęp do katalogu „<xliff:g id="DIRECTORY">%1$s</xliff:g>”"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Zezwolić na dostęp do katalogu „<xliff:g id="DIRECTORY">%1$s</xliff:g>” na urządzeniu „<xliff:g id="ROOT">%2$s</xliff:g>”?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Aplikacja „<xliff:g id="APPNAME">%1$s</xliff:g>” uzyska pełny dostęp do plików zapisanych obecnie w tej lokalizacji i do wszystkich treści, które pojawią się tu w przyszłości."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Szukaj na telefonie"</string>
 </resources>
diff --git a/res/values-pt-rBR/config.xml b/res/values-pt-rBR/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-pt-rBR/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index af691a1..4ac27f4 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Compartilhar"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Excluir"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Selecionar tudo"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Selecionar"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Classificar por…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiar para..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Mover para…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compactar"</string>
@@ -64,10 +66,21 @@
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamanho"</string>
-    <string name="sort_dimension_date" msgid="4231005651895254033">"Modificação"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nome do arquivo (A a Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (A a Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamanho (menor primeiro)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Mais antigo primeiro"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nome do arquivo (Z a A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (Z a A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamanho (maior primeiro)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Mais recente primeiro"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Classificar por"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Classificado por <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Número de itens"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Crescente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Decrescente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raízes"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ocultar raízes"</string>
     <string name="save_error" msgid="8631128801982095782">"Falha ao salvar o documento"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Desfazer"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparando para copiar..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparando para compactar…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparando para extrair…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparando para mover..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparando-se para excluir..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparando..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparando..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparando..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparando..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparando..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Conceder acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> para <xliff:g id="APPNAME"><b>^1</b></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Não perguntar novamente"</string>
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Negar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arquivo<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Substituir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuar em segundo plano"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Arquivos recentes no smartphone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Arquivos no smartphone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> no smartphone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Arquivos no <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Arquivos do <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Arquivos do <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imagens recentes no smartphone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imagens no smartphone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imagens no <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imagens do <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imagens do <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imagens"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Áudio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documentos"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nome da pasta"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novo nome"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Visualizar o arquivo <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Procurar arquivos em outros apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anônimo"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permitir acesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Permitir acesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" no \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Isso permitirá que o app \"<xliff:g id="APPNAME">%1$s</xliff:g>\" tenha acesso total a todos os arquivos armazenados atualmente nesse local e ao conteúdo armazenado aqui futuramente."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Pesquisar neste smartphone"</string>
 </resources>
diff --git a/res/values-pt-rPT/config.xml b/res/values-pt-rPT/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-pt-rPT/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 9a71ed4..e4c6865 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Partilhar"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Eliminar"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Selecionar tudo"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Selecionar"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Ordenar por…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiar para…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Mover para..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string>
@@ -48,7 +50,7 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"Copiar"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"Colar"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"Colar na pasta"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"Mostrar mem. armaz. int."</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"Mostrar armaz. interno"</string>
     <string name="menu_advanced_hide" msgid="6488381508009246334">"Ocultar mem. armaz. int."</string>
     <string name="button_select" msgid="240863497069321364">"Selecionar"</string>
     <string name="button_copy" msgid="8219059853840996027">"Copiar"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamanho"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nome do ficheiro (A a Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (A a Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamanho (o mais pequeno 1.º)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modificado (o mais antigo 1.º)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nome do ficheiro (Z a A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (Z a A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamanho (o maior 1.º)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modificado (o mais recente 1.º)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Ordenar por"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Classificado por <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Número de itens"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Ascendente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Descendente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Abrir a aplicação <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raízes"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ocultar raízes"</string>
     <string name="save_error" msgid="8631128801982095782">"Falha ao guardar o documento"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">A eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> item…</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Anular"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"A preparar para copiar…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"A preparar para comprimir…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"A preparar para extrair…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"A preparar para mover…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"A preparar para eliminar…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"A preparar…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"A preparar…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"A preparar…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"A preparar…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"A preparar…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no(a) <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no(a) <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Não perguntar novamente"</string>
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Recusar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arquivo<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Pretende substituir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuar em segundo plano"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Ficheiros recentes no telemóvel"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Ficheiros no telemóvel"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> no telemóvel"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Ficheiros no dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Ficheiros de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Ficheiros de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imagens recentes no telemóvel"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imagens no telemóvel"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imagens no dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imagens de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imagens de <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imagens"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Áudio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documentos"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nome da pasta"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novo nome"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Pré-visualizar o ficheiro <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Procure ficheiros noutras aplicações"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anónimo"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permitir acesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Irá permitir que a aplicação \"<xliff:g id="APPNAME">%1$s</xliff:g>\" tenha acesso total a todos os ficheiros atualmente armazenados nesta localização e a qualquer conteúdo armazenado aqui no futuro."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Pesquise este telemóvel."</string>
 </resources>
diff --git a/res/values-pt/config.xml b/res/values-pt/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-pt/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index af691a1..4ac27f4 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Compartilhar"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Excluir"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Selecionar tudo"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Selecionar"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Classificar por…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiar para..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Mover para…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Compactar"</string>
@@ -64,10 +66,21 @@
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Resumo"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tipo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Tamanho"</string>
-    <string name="sort_dimension_date" msgid="4231005651895254033">"Modificação"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"Modificado"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nome do arquivo (A a Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tipo (A a Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Tamanho (menor primeiro)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Mais antigo primeiro"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nome do arquivo (Z a A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tipo (Z a A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Tamanho (maior primeiro)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Mais recente primeiro"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Classificar por"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Classificado por <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Número de itens"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Crescente"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Decrescente"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Mostrar raízes"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ocultar raízes"</string>
     <string name="save_error" msgid="8631128801982095782">"Falha ao salvar o documento"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Desfazer"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Preparando para copiar..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Preparando para compactar…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Preparando para extrair…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Preparando para mover..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Preparando-se para excluir..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Preparando..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Preparando..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Preparando..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Preparando..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Preparando..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Conceder acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> para <xliff:g id="APPNAME"><b>^1</b></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Não perguntar novamente"</string>
     <string name="allow" msgid="1275746941353040309">"Permitir"</string>
     <string name="deny" msgid="5127201668078153379">"Negar"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arquivo<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Substituir <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuar em segundo plano"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Arquivos recentes no smartphone"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Arquivos no smartphone"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> no smartphone"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Arquivos no <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Arquivos do <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Arquivos do <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imagens recentes no smartphone"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imagens no smartphone"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imagens no <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imagens do <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imagens do <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imagens"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Áudio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Vídeos"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documentos"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Nome da pasta"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novo nome"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Visualizar o arquivo <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Procurar arquivos em outros apps"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anônimo"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permitir acesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Permitir acesso a \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" no \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Isso permitirá que o app \"<xliff:g id="APPNAME">%1$s</xliff:g>\" tenha acesso total a todos os arquivos armazenados atualmente nesse local e ao conteúdo armazenado aqui futuramente."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Pesquisar neste smartphone"</string>
 </resources>
diff --git a/res/values-ro/config.xml b/res/values-ro/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ro/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index c14d37f..3507b5f 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Trimiteți"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Ștergeți"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Selectați-le pe toate"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Selectați"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortați după…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Copiați în…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Mutați în…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Comprimați"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tip"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Dimensiune"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ultima modificare"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Numele fișierului (de la A la Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tip (de la A la Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Dimensiune (întâi cele mai mici)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Data modificării (întâi cele mai vechi)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Numele fișierului (de la Z la A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tip (de la Z la A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Dimensiune (întâi cele mai mari)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Data modificării (întâi cele mai noi)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortați după"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sortate după <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Numărul de articole"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"În ordine crescătoare"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"În ordine descrescătoare"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Deschideți <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Afișați directoarele rădăcină"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ascundeți directoarele rădăcină"</string>
     <string name="save_error" msgid="8631128801982095782">"Salvarea documentului nu a reușit"</string>
@@ -117,11 +130,11 @@
       <item quantity="one">Se șterge <xliff:g id="COUNT_0">%1$d</xliff:g> articol.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Anulați"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Se pregătește copierea…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Se pregătește comprimarea…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Se pregătește extragerea…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Se pregătește mutarea…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Se pregătește ștergerea…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Se pregătește..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Se pregătește..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Se pregătește..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Se pregătește..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Se pregătește..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="few">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> articole</item>
@@ -188,7 +201,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să acceseze directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de pe <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să acceseze directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să vă acceseze datele, inclusiv fotografiile și videoclipurile, de pe <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Nu mai întreba"</string>
     <string name="allow" msgid="1275746941353040309">"Permiteți"</string>
     <string name="deny" msgid="5127201668078153379">"Refuzați"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -227,4 +239,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhivă<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Suprascrieți <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Continuați în fundal"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selectat</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Fișiere recente pe telefon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Fișiere pe telefon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> pe telefon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Fișiere pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Fișiere de la <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Fișiere de la <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imagini recente de pe telefon"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imagini de pe telefon"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imagini de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imagini din <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imagini din <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imagini"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videoclipuri"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Documente"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Numele dosarului"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nume nou"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Previzualizați fișierul <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Căutați fișiere în alte aplicații"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonim"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Permiteți accesul la „<xliff:g id="DIRECTORY">%1$s</xliff:g>”"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Permiteți accesul la „<xliff:g id="DIRECTORY">%1$s</xliff:g>” pe „<xliff:g id="ROOT">%2$s</xliff:g>”?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"„<xliff:g id="APPNAME">%1$s</xliff:g>” va avea acces complet la toate fișierele stocate momentan în această locație și la tot conținutul stocat aici în viitor."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Căutați în acest telefon"</string>
 </resources>
diff --git a/res/values-ru/config.xml b/res/values-ru/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ru/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 6778c9f..a8714e7 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Поделиться"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Удалить"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Выбрать все"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Выбрать"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Сортировать"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Копировать в…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Переместить в..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Сжать"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Размер"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Изменено"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"названию (от А до Я)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"типу (от А до Я)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"размеру (с маленьких)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"изменениям (со старых)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"названию (от Я до А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"типу (от Я до А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"размеру (с больших)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"изменениям (с новых)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Сортировка"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Отсортировано по <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Количество объектов"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"По возрастанию"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"По убыванию"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Открыть приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="drawer_open" msgid="8071673398187261741">"Показать корневые папки"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Скрыть корневые папки"</string>
     <string name="save_error" msgid="8631128801982095782">"Не удалось сохранить документ"</string>
@@ -122,11 +135,11 @@
       <item quantity="other">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файла…</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Отменить"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Подготовка к копированию…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Подготовка к сжатию…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Подготовка к извлечению…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Подготовка к перемещению…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Подготовка к удалению…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Подготовка…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Подготовка…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Подготовка…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Подготовка…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Подготовка…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> из <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\"?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>: открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к вашим данным, включая фото и видео?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Больше не спрашивать"</string>
     <string name="allow" msgid="1275746941353040309">"Разрешить"</string>
     <string name="deny" msgid="5127201668078153379">"Запретить"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"Архив<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Заменить файл <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Продолжить в фоновом режиме"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="few">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="many">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Недавно открытые на телефоне"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Файлы на телефоне"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> на телефоне"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Файлы на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Файлы из сервиса \'<xliff:g id="LABEL">%1$s</xliff:g>\'"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Файлы из сервиса \'<xliff:g id="LABEL">%1$s</xliff:g>\' (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Недавние изображения на телефоне"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Изображения на телефоне"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Изображения на устройстве \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Изображения из сервиса \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Изображения из сервиса \"<xliff:g id="LABEL">%1$s</xliff:g>\" (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Изображения"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аудио"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Видео"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документы"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Название папки"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Новое название"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Открыть файл \"<xliff:g id="FILENAME">%1$s</xliff:g>\" в режиме предпросмотра."</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Найти файлы в других приложениях"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Анонимное приложение"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Открыть доступ к папке \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Открыть доступ к папке \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" (<xliff:g id="ROOT">%2$s</xliff:g>)?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" получит полный доступ ко всем файлам, которые хранятся в этой папке сейчас или будут помещены в нее позже."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Поиск на этом телефоне"</string>
 </resources>
diff --git a/res/values-si/config.xml b/res/values-si/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-si/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index e7eff9e..b513e65 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"බෙදාගන්න"</string>
     <string name="menu_delete" msgid="1022254131543256626">"මකන්න"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"සියල්ල තෝරන්න"</string>
+    <string name="menu_select" msgid="1366061076507142387">"තෝරන්න"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"අනුපිළිවෙළට සකසන්න..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"වෙත පිටපත් කරන්න..."</string>
     <string name="menu_move" msgid="2310760789561129882">"වෙත ගෙනයන්න..."</string>
     <string name="menu_compress" msgid="37539111904724188">"සම්පීඩනය කරන්න"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"වර්ගය"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"තරම"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"වෙනස් කළේ"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ගොනු නම (A සිට Z දක්වා)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"වර්ගය (A සිට Z දක්වා)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"තරම (කුඩාතම පළමුව)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"වෙනස් කරන ලදී (පැරණිතම පළමුව)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ගොනු නම (Z සිට A දක්වා)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"වර්ගය (Z සිට A දක්වා)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"තරම (විශාලතම පළමුව)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"වෙනස් කරන ලදී (නවතම පළමුව)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"අනුපිළිවෙළට සකසන්න"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> අනුව අනුපිළිවෙළට සකසන ලදී"</string>
     <string name="directory_items" msgid="6645621978998614003">"අයිතම ගණන:"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ආරෝහණ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"අවරෝහණ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> විවෘත කරන්න"</string>
     <string name="drawer_open" msgid="8071673398187261741">"මුල් පෙන්වන්න"</string>
     <string name="drawer_close" msgid="4263880768630848848">"මුල් සඟවන්න"</string>
     <string name="save_error" msgid="8631128801982095782">"ලේඛනය සුරැකීම අසාර්ථක විය"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකමින්.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"අස් කරන්න"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"පිටපතක් සඳහා සූදානම් කරමින්..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"සම්පීඩනය කිරීම සඳහා සූදානම් කරමින්…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"උද්ධෘත කිරීමට ලෑස්ති වෙමින්…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"ගෙන යාම සඳහා පිළියෙළ කරමින් ..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"මැකීම සඳහා සූදානම් කරමින්..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"සූදානම් කරමින්…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"සූදානම් කරමින්…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"සූදානම් කරමින්…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"සූදානම් කරමින්…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"සූදානම් කරමින්…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g>ක් පිටපත් කළ නොහැකි විය</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> හට <xliff:g id="STORAGE"><i>^3</i></xliff:g> මත <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ප්‍රවේශය දෙන්නද?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ප්‍රවේශය <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ලබා දෙන්නද?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> හි, ඡායාරූප සහ වීඩියෝ ඇතුළුව, ඔබේ දත්තවලට <xliff:g id="APPNAME"><b>^1</b></xliff:g> හට ප්‍රවේශය ලබා දෙන්නද?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"නැවත නොඅසන්න"</string>
     <string name="allow" msgid="1275746941353040309">"ඉඩ දෙන්න"</string>
     <string name="deny" msgid="5127201668078153379">"ප්‍රතික්ෂේප කරන්න"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"සංරක්ෂිත<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> උඩින් ලියන්නද?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"පසුබිමෙහි කරන්න"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ක් තෝරන ලදි</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ක් තෝරන ලදි</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"දුරකථනයේ මෑත ගොනු"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"දුරකථනයේ ගොනු"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"දුරකථනයේ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> හි ගොනු"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> වෙතින් ගොනු"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> වෙතින් ගොනු"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"දුරකථනයේ ඇති මෑත රූප"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"දුරකථනයේ ඇති රූප"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> මත රූප"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> වෙතින් රූප"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> වෙතින් රූප"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"රූප"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ශ්‍රව්‍ය"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"වීඩියෝ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ලේඛන"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ෆෝල්ඩරයේ නම"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"අලුත් නම"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> ගොනුව පෙර දකින්න"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"වෙනත් යෙදුම්වල ගොනු බ්‍රවුස් කරන්න"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"නිර්නාමික"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" වෙත ප්‍රවේශයට ඉඩ දෙන්න"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" මත \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" වෙත ප්‍රවේශයට ඉඩ දෙන්නේද?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"එය දැනට මෙම ස්ථානයේ ගබඩා කර ඇති සියලුම ගොනු, සහ මෙහි අනාගතය ගොනු කෙරෙන ඕනෑම අන්තර්ගතයක් වෙත \"<xliff:g id="APPNAME">%1$s</xliff:g>\" හට සම්පූර්ණ ප්‍රවේශයට ඉඩ දෙයි."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"මෙම දුරකථනයේ සොයන්න"</string>
 </resources>
diff --git a/res/values-sk/config.xml b/res/values-sk/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-sk/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index f145c9a..4f83d9a 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Zdieľať"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Odstrániť"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Vybrať všetko"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Vybrať"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Zoradiť podľa…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopírovať do…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Presunúť do…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Komprimovať"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Typ"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Veľkosť"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Upravené"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Názov súboru (A – Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Typ (A – Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Veľkosť (od najmenších)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Upravené (od najstarších)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Názov súboru (Z – A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Typ (Z – A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Veľkosť (od najväčších)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Upravené (od najnovších)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Zoradenie podľa"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Zoradiť podľa <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Počet položiek"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Vzostupne"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Zostupne"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Otvoriť aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Zobraziť korene"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Skryť korene"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokument sa nepodarilo uložiť"</string>
@@ -122,11 +135,11 @@
       <item quantity="one">Odstraňujte sa <xliff:g id="COUNT_0">%1$d</xliff:g> položka.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Späť"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Pripravuje sa na kopírovanie..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Prebieha príprava komprimovania…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Pripravuje sa extrahovanie…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Prebieha príprava na presunutie…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Príprava na odstránenie…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Pripravuje sa…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Pripravuje sa…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Pripravuje sa…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Pripravuje sa…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Pripravuje sa…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="few">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložisku <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Chcete aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> udeliť prístup k dátam (vrátane fotiek a videí) v úložisku <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Nabudúce sa nepýtať"</string>
     <string name="allow" msgid="1275746941353040309">"Povoliť"</string>
     <string name="deny" msgid="5127201668078153379">"Zamietnuť"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,35 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archív<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Prepísať názov <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Pokračovať na pozadí"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="few">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="many">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Vybrané: <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nedávne súbory v telefóne"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Súbory v telefóne"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> v telefóne"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Súbory v zariadení <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Súbory zo služby <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Súbory z: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nedávne obrázky v telefóne"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Obrázky v telefóne"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Obrázky v zariadení <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Obrázky zo služby <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Obrázky zo služby <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Obrázky"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Zvuk"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videá"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenty"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Názov priečinka"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nové názov"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Zobraziť ukážku súboru <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Prehliadanie súborov v iných aplikáciách"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymná"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Povoliť prístup k adresáru <xliff:g id="DIRECTORY">%1$s</xliff:g>"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Umožní aplikácii <xliff:g id="APPNAME">%1$s</xliff:g> úplný prístup k všetkým súborom aktuálne uloženým v tomto umiestnení a všetkému obsahu, ktorý tu bude uložený v budúcnosti."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Hľadajte v tomto telefóne"</string>
 </resources>
diff --git a/res/values-sl/config.xml b/res/values-sl/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-sl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index d462cbe..49b72a1 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Deli z drugimi"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Izbriši"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Izberi vse"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Izberi"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Razvrsti po …"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiraj v …"</string>
     <string name="menu_move" msgid="2310760789561129882">"Premakni v ..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Stisni"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Vrsta"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Velikost"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Spremenjeno"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Ime datoteke (od A do Ž)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Vrsta (od A do Ž)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Velikost (od najmanjše)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Spremenjeno (od najstarejše)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Ime datoteke (od Ž do A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Vrsta (od Ž do A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Velikost (od največje)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Spremenjeno (od najnovejše)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Razvrsti po"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Razvrščeno po: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Število elementov"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Naraščajoče"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Padajoče"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Odpri aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Pokaži korene"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Skrij korene"</string>
     <string name="save_error" msgid="8631128801982095782">"Dokumenta ni bilo mogoče shraniti"</string>
@@ -122,11 +135,11 @@
       <item quantity="other">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> elementov.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Razveljavi"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Pripravljanje na kopiranje …"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Pripravljanje na stiskanje …"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Priprava na ekstrahiranje …"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Priprava na premikanje …"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Pripravljanje na izbris …"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Pripravljanje …"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Pripravljanje …"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Pripravljanje …"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Pripravljanje …"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Pripravljanje …"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> elementa ni bilo mogoče kopirati</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v shrambi <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Želite aplikaciji dovoliti <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostop do podatkov, vključno s fotografijami in videoposnetki, v shrambi <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ne sprašuj več"</string>
     <string name="allow" msgid="1275746941353040309">"Dovoli"</string>
     <string name="deny" msgid="5127201668078153379">"Zavrni"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arhiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Želite prepisati <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Nadaljuj v ozadju"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izbran</item>
+      <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrana</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrani</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> izbranih</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Nedavne datoteke v telefonu"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Datoteke v telefonu"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> v telefonu"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Datoteke v napravi <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Datoteke iz: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Datoteke iz: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Nedavne slike v telefonu"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Slike v telefonu"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Slike v napravi <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Slike iz storitve <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Slike iz storitve <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Slike"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Zvok"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videoposnetki"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Ime mape"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Novo ime"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Predogled datoteke <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Brskanje po datotekah v drugih aplikacijah"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonimno"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Dovoli dostop do imenika »<xliff:g id="DIRECTORY">%1$s</xliff:g>«"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Želite dovoliti dostop do imenika »<xliff:g id="DIRECTORY">%1$s</xliff:g>« v korenskem imeniku »<xliff:g id="ROOT">%2$s</xliff:g>«?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"S tem bo aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> imela poln dostop do vseh datotek, ki so trenutno shranjene na tej lokaciji, in vsebine, ki bo na tej lokaciji shranjena v prihodnje."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Iščite v tem telefonu"</string>
 </resources>
diff --git a/res/values-sq/config.xml b/res/values-sq/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-sq/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 3e31507..92ec0c4 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Ndaj"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Fshi"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Zgjidhi të gjitha"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Zgjidh"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Rendit sipas..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopjo te..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Zhvendos te..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Ngjish"</string>
@@ -64,10 +66,21 @@
     <string name="sort_dimension_summary" msgid="7724534446881397860">"Përmbledhja"</string>
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Lloji"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Madhësia"</string>
-    <string name="sort_dimension_date" msgid="4231005651895254033">"U modifikua"</string>
+    <string name="sort_dimension_date" msgid="4231005651895254033">"Modifikuar"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Emri i skedarit (A-Zh)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Lloji (A-Zh)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Madhësia (më e vogla në fillim)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Modifikuar (më e vjetra në fillim)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Emri i skedarit (Zh-A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Lloji (Zh-A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Madhësia (më e madhja në fillim)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Modifikuar (më e reja në fillim)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Rendit sipas"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Renditur sipas <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Numri i artikujve"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Në rritje"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Në zbritje"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Hap <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Trego rrënjët"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Fshih rrënjët"</string>
     <string name="save_error" msgid="8631128801982095782">"Ruajtja e dokumentit dështoi"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> artikull po fshihet.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Zhbëj"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Po përgatitet për kopjimin…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Po përgatitet për ngjeshjen…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Për përgatitet për nxjerrje…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Po përgatitet për zhvendosjen…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Po përgatitet për fshirje…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Po përgatitet…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Po përgatitet…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Po përgatitet…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Po përgatitet…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Po përgatitet…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> artikuj nuk mund të kopjoheshin</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Jepi aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> në <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te të dhënat, duke përfshirë fotografitë dhe videot, në <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Mos pyet përsëri"</string>
     <string name="allow" msgid="1275746941353040309">"Lejo"</string>
     <string name="deny" msgid="5127201668078153379">"Refuzo"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arkiva<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Të mbishkruhet <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Vazhdo në sfond"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të zgjedhura</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> i zgjedhur</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Skedarët më të fundit në telefon"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Skedarët në telefon"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> në telefon"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Skedarët në <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Skedarët nga <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Skedarët nga <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Imazhet e fundit në telefon"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Imazhet nga telefoni"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Imazhet në <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Imazhet nga <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Imazhet nga <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Imazhet"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videot"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokumentet"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Emri i dosjes"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Emri i ri"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Shiko paraprakisht skedarin <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Shfleto skedarët në aplikacionet e tjera"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonim"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Lejo qasjen në \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Të lejohet qasja në \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" në \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Do të lejojë që \"<xliff:g id="APPNAME">%1$s</xliff:g>\" të ketë qasje të plotë në të gjithë skedarët e ruajtur aktualisht në këtë vendndodhje dhe çdo përmbajtje të ardhshme të ruajtur këtu."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Kërko në këtë telefon"</string>
 </resources>
diff --git a/res/values-sr/config.xml b/res/values-sr/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-sr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index a36c3eb..14a9b2f 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Дели"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Избриши"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Изабери све"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Изабери"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Сортирај према..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Копирај у…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Премести у…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Компримуј"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Величина"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Измењено"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Назив датотеке (A–Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Тип (од A до Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Величина (прво најмања)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Мењано (прво најстарије)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Назив датотеке (Z–A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Тип (од Z до A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Величина (прво највећа)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Мењано (прво најновије)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Сортирање према"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Сортирано према: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Број ставки"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Растуће"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Опадајуће"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Отворите апликацију <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Прикажи основне директоријуме"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Сакриј основне директоријуме"</string>
     <string name="save_error" msgid="8631128801982095782">"Чување документа није успело"</string>
@@ -117,11 +130,11 @@
       <item quantity="other">Брише се <xliff:g id="COUNT_1">%1$d</xliff:g> ставки.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Опозови"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Припремамо копирање…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Припремају се за компримовање…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Издвајање се припрема…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Припремамо премештање…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Припремамо брисање…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Припрема се..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Припрема се..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Припрема се..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Припрема се..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Припрема се..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> ставке није успело</item>
@@ -188,7 +201,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Желите ли да дозволите апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> да приступа директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на меморијском простору <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Желите ли да дозволите апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> да приступа директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Желите ли да дозволите апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> да приступа подацима, укључујући слике и видео, на меморијском простору <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Не питај поново"</string>
     <string name="allow" msgid="1275746941353040309">"Дозволи"</string>
     <string name="deny" msgid="5127201668078153379">"Одбиј"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -227,4 +239,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"архива<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Желите да замените <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Настави у позадини"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Изабрана је <xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
+      <item quantity="few">Изабране су <xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item>
+      <item quantity="other">Изабрано је <xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Недавне датотеке на телефону"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Датотеке на телефону"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> на телефону"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Датотеке на уређају <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Датотеке из апликације <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Датотеке из апликације <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Недавне слике на телефону"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Слике на телефону"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Слике на уређају <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Слике из: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Слике из: <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Слике"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Звук"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Видео снимци"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документи"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Назив директоријума"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Нови назив"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Прегледајте датотеку <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Прегледајте датотеке у другим апликацијама"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Анонимна"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Дозволите приступ директоријуму „<xliff:g id="DIRECTORY">%1$s</xliff:g>“"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Желите ли да дозволите приступ директоријуму „<xliff:g id="DIRECTORY">%1$s</xliff:g>“ на „<xliff:g id="ROOT">%2$s</xliff:g>“?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"То ће дозволити апликацији „<xliff:g id="APPNAME">%1$s</xliff:g>“ да има потпун приступ свим датотекама које се тренутно чувају на овој локацији, као и било ком садржају који ће се ту чувати у будућности."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Претражите овај телефон"</string>
 </resources>
diff --git a/res/values-sv/config.xml b/res/values-sv/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-sv/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 7eab784..b097916 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Dela"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Radera"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Markera alla"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Välj"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sortera efter …"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopiera till …"</string>
     <string name="menu_move" msgid="2310760789561129882">"Flytta till ..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Komprimera"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Filtyp"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Storlek"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ändrades senast"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Filnamn (A till Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Typ (A till Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Storlek (minsta först)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Ändrad (äldsta först)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Filnamn (Z till A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Typ (Z till A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Size (största först)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Ändrade (senaste först)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sortera efter"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sorterat efter <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Antal objekt"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Stigande"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Fallande"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Öppna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Visa rötter"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Dölj rötter"</string>
     <string name="save_error" msgid="8631128801982095782">"Det gick inte att spara dokumentet"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> objekt raderas.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Ångra"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopieringen förbereds"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Komprimeringen förbereds"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Extraheringen förbereds …"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Förbereder för att flytta …"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Radering förbereds …"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Förbereder …"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Förbereder …"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Förbereder …"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Förbereder …"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Förbereder …"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> objekt gick inte att kopiera.</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till din data (inklusive foton och videor) på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Fråga inte igen"</string>
     <string name="allow" msgid="1275746941353040309">"Tillåt"</string>
     <string name="deny" msgid="5127201668078153379">"Neka"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arkiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Vill du skriva över <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Fortsätt i bakgrunden"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> har valts</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> har valts</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Senaste filerna på mobilen"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Filer på mobilen"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> på mobilen"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Filer på <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Filer från <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Filer från <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Senaste bilderna på mobilen"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Bilder på mobilen"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Bilder på <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Bilder från <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Bilder från <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Bilder"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Ljud"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videor"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokument"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Mappnamn"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Nytt namn"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Förhandsgranska filen <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Bläddra efter filer i andra appar"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonym"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Vill du tillåta åtkomst till <xliff:g id="DIRECTORY">%1$s</xliff:g>"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Vill du tillåta åtkomst till <xliff:g id="DIRECTORY">%1$s</xliff:g> på <xliff:g id="ROOT">%2$s</xliff:g>?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Tillåter att <xliff:g id="APPNAME">%1$s</xliff:g> får fullständig åtkomst till alla nuvarande och framtida filer som lagras här."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Sök på mobilen"</string>
 </resources>
diff --git a/res/values-sw/config.xml b/res/values-sw/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-sw/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 5063641..3ab2f35 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Shiriki"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Futa"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Chagua zote"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Chagua"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Panga kulingana na..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Nakili kwenye..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Hamishia kwenye..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Bana"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Aina"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Ukubwa"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Ilibadilishwa"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Jina la faili (A hadi Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Aina (A hadi Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Ukubwa (ndogo kwanza)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Imebadilishwa (za zamani kwanza)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Jina la faili (Z hadi A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Aina (Z hadi A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Ukubwa (kubwa kwanza)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Imebadilishwa (mpya kwanza)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Panga kulingana na"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Imepangwa kwa <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Idadi ya vipengee"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Kupanga kwa kupanda"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Kupanga kwa kushuka"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Fungua <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Onyesha nyenzo"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ficha nyenzo"</string>
     <string name="save_error" msgid="8631128801982095782">"Imeshindwa kuhifadhi hati"</string>
@@ -112,15 +125,15 @@
       <item quantity="one">Inafuta kipengee <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Tendua"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Inaanda kunakili..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Inaandaa kubana faili…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Inajitayarisha kutoa…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Inatayarisha kuhamisha..."</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Inajitayarisha kufuta..."</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Inaandaa..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Inaandaa..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Inaandaa..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Inaandaa..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Inaandaa..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
-      <item quantity="other">Imeshindwa kunakili vipengee <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Imeshindwa kunakili kipengee <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+      <item quantity="other">Imeshindwa kunakili faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Imeshindwa kunakili faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
     </plurals>
     <plurals name="compress_error_notification_title" formatted="false" msgid="3043630066678213644">
       <item quantity="other">Haikuweza kubana faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kwenye <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie data yako, ikiwa ni pamoja na picha na video kwenye <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Usiulize tena"</string>
     <string name="allow" msgid="1275746941353040309">"Ruhusu"</string>
     <string name="deny" msgid="5127201668078153379">"Usikubali"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"weka <xliff:g id="EXTENSION">%s</xliff:g> kwenye kumbukumbu"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Ungependa kubadili <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Endelea shughuli chini chini"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">Umechagua <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Umechagua <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Faili za hivi majuzi zilizo kwenye simu"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Faili zilizo kwenye simu"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> kwenye simu"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Faili zilizo kwenye <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Faili kutoka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Faili kutoka <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Picha za hivi majuzi zilizo kwenye simu"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Picha kwenye simu"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Picha kwenye <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Picha kutoka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Picha kutoka <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Picha"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Sauti"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Hati"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Jina la folda"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Jina jipya"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Kagua faili ya <xliff:g id="FILENAME">%1$s</xliff:g> kwanza"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Vinjari faili katika programu zingine"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Haijulikani"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Ruhusu ifikie \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Ungependa kuruhusu ifikie \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" kwenye \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Itaipa \"<xliff:g id="APPNAME">%1$s</xliff:g>\" idhini kamili za kufikia faili zote ambazo umehifadhi kwa sasa katika eneo hili na maudhui yoyote utakayohifadhi hapa."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Tafuta simu hii"</string>
 </resources>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index 1b67ee5..07a1887 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -17,8 +17,14 @@
 <resources>
     <dimen name="list_item_height">64dp</dimen>
     <dimen name="list_item_padding">24dp</dimen>
+    <dimen name="list_item_icon_padding">12dp</dimen>
 
     <dimen name="list_divider_inset">80dp</dimen>
 
     <dimen name="max_drawer_width">320dp</dimen>
+
+    <dimen name="search_bar_background_margin_start">280dp</dimen>
+    <dimen name="search_bar_background_margin_end">280dp</dimen>
+    <dimen name="search_bar_text_margin_start">270dp</dimen>
+    <dimen name="search_bar_text_margin_end">182dp</dimen>
 </resources>
diff --git a/res/values-sw720dp/config.xml b/res/values-sw720dp/config.xml
index 4898e74..b6444d8 100644
--- a/res/values-sw720dp/config.xml
+++ b/res/values-sw720dp/config.xml
@@ -17,4 +17,6 @@
 <resources>
     <!-- Indicates if search view is taking the whole toolbar space -->
     <bool name="full_bar_search_view">false</bool>
+
+    <string name="scrolling_behavior" translatable="false">@string/appbar_scrolling_view_behavior</string>
 </resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 982b204..7ce3b53 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -19,6 +19,15 @@
     <dimen name="grid_padding_vert">16dp</dimen>
 
     <dimen name="list_item_padding">24dp</dimen>
+    <dimen name="list_item_width">80dp</dimen>
 
     <dimen name="max_drawer_width">320dp</dimen>
+
+    <dimen name="search_bar_background_margin_start">120dp</dimen>
+    <dimen name="search_bar_background_margin_end">120dp</dimen>
+    <dimen name="search_bar_text_margin_start">55dp</dimen>
+    <dimen name="search_bar_text_margin_end">24dp</dimen>
+    <dimen name="search_bar_icon_padding">16dp</dimen>
+
+    <dimen name="action_bar_space_margin">0dp</dimen>
 </resources>
diff --git a/res/values-ta/config.xml b/res/values-ta/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ta/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index cac3838..ad3131f 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"பகிர்"</string>
     <string name="menu_delete" msgid="1022254131543256626">"நீக்கு"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"எல்லாம் தேர்ந்தெடு"</string>
+    <string name="menu_select" msgid="1366061076507142387">"தேர்ந்தெடு"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"இதன்படி வரிசைப்படுத்து..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"இங்கு நகலெடு…"</string>
     <string name="menu_move" msgid="2310760789561129882">"இங்கு நகர்த்து…"</string>
     <string name="menu_compress" msgid="37539111904724188">"அளவைக் குறை"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"வகை"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"அளவு"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"மாற்றியது"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ஃபைல் பெயர் (A முதல் Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"வகை (A முதல் Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"அளவு (சிறியது முதலில்)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"திருத்தியது (பழையது முதலில்)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ஃபைல் பெயர் (Z முதல் A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"வகை (Z முதல் A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"அளவு (பெரியது முதலில்)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"திருத்தியது (புதியது முதலில்)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"இதன்படி வரிசைப்படுத்து"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> வரிசைப்படி"</string>
     <string name="directory_items" msgid="6645621978998614003">"உருப்படிகளின் எண்ணிக்கை"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ஏறுவரிசையில்"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"இறங்குவரிசையில்"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸைத் திறக்கும்"</string>
     <string name="drawer_open" msgid="8071673398187261741">"சேமித்த இடத்தைக் காட்டு"</string>
     <string name="drawer_close" msgid="4263880768630848848">"சேமித்த இடத்தை மறை"</string>
     <string name="save_error" msgid="8631128801982095782">"ஆவணத்தைச் சேமிக்க முடியவில்லை"</string>
@@ -76,7 +89,7 @@
     <string name="root_recent" msgid="1080156975424341623">"சமீபத்தியவை"</string>
     <string name="root_available_bytes" msgid="8269870862691408864">"பயன்படுத்தாத அளவு: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="6521366147466512289">"சேமிப்பகச் சேவைகள்"</string>
-    <string name="root_type_shortcut" msgid="6059343175525442279">"குறுக்குவழிகள்"</string>
+    <string name="root_type_shortcut" msgid="6059343175525442279">"ஷார்ட்கட்கள்"</string>
     <string name="root_type_device" msgid="1713604128005476585">"சாதனங்கள்"</string>
     <string name="root_type_apps" msgid="8646073235029886342">"மேலும் பயன்பாடுகள்"</string>
     <string name="empty" msgid="5300254272613103004">"எதுவும் இல்லை"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்குகிறது.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"செயல்தவிர்"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"நகலெடுக்க, தயார்படுத்துகிறது…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"அளவைக் குறைக்க தயாராகிறது…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"பிரிப்பதற்குத் தயாராகிறது…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"நகர்த்த, தயார்படுத்துகிறது…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"நீக்க, தயார்படுத்துகிறது…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"தயாராகிறது..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"தயாராகிறது..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"தயாராகிறது..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"தயாராகிறது..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"தயாராகிறது..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> உருப்படிகளை நகலெடுக்க முடியவில்லை</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> இல் உள்ள <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> இல் உள்ள படங்கள், வீடியோக்கள் உட்பட எல்லா தரவையும் அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"மீண்டும் கேட்காதே"</string>
     <string name="allow" msgid="1275746941353040309">"அனுமதி"</string>
     <string name="deny" msgid="5127201668078153379">"நிராகரி"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"காப்பகம்<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g>ஐ மேலெழுதவா?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"பின்னணியில் தொடர்க"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"மொபைலில் உள்ள சமீபத்திய ஃபைல்கள்"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"மொபைலில் உள்ள ஃபைல்கள்"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"மொபைலில் உள்ள <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> இலுள்ள ஃபைல்கள்"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> இலிருந்து ஃபைல்கள்"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> இலிருந்து ஃபைல்கள்"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"மொபைலிலுள்ள சமீபத்திய படங்கள்"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"மொபைலில் உள்ள படங்கள்"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>ல் உள்ள படங்கள்"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>ல் இருந்த படங்கள்"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>ல் இருந்த படங்கள்"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"படங்கள்"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ஆடியோ"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"வீடியோக்கள்"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"ஆவணங்கள்"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"கோப்புறையின் பெயர்"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"புதிய பெயர்"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> என்ற ஃபைல் மாதிரிக்காட்சியாகத் தெரியும்"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ஃபைல்களை வேறு ஆப்ஸில் தேடவும்"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"பெயர் குறிப்பிடாதது"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"க்கு அணுகல் வழங்கு"</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"இந்த இருப்பிடத்தில் தற்போது சேமிக்கப்பட்டிருப்பவை, எதிர்காலத்தில் சேமிக்கப்படுபவை என எல்லாக் கோப்புகளுக்குமான முழு அணுகலையும் \"<xliff:g id="APPNAME">%1$s</xliff:g>\"க்கு அனுமதிக்கும்."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"இந்த மொபைலில் தேடவும்"</string>
 </resources>
diff --git a/res/values-te/config.xml b/res/values-te/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-te/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 68ac482..b624cdc 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"భాగస్వామ్యం చేయి"</string>
     <string name="menu_delete" msgid="1022254131543256626">"తొలగించు"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"అన్నింటినీ ఎంచుకోండి"</string>
+    <string name="menu_select" msgid="1366061076507142387">"ఎంచుకోండి"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"దీన్ని బట్టి క్రమీకరించు…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"ఇక్కడికి కాపీ చేయి…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ఇక్కడికి తరలించు..."</string>
     <string name="menu_compress" msgid="37539111904724188">"కుదించు"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"రకం"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"పరిమాణం"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"సవరించిన సమయం"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ఫైల్ పేరు (A నుండి Zకు)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"రకం (A నుండి Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"పరిమాణం (మొదట చిన్నవి)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"సవరించబడినవి (మొదట పాతవి)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ఫైల్ పేరు (Z నుండి Aకు)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"రకం (Z నుండి A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"పరిమాణం (మొదట పెద్దవి)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"సవరించబడినవి (మొదట సరికొత్తవి)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"దీన్ని బట్టి క్రమీకరించు"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"<xliff:g id="LABEL">%s</xliff:g> ద్వారా క్రమీకరించబడింది"</string>
     <string name="directory_items" msgid="6645621978998614003">"అంశాల సంఖ్య"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"ఆరోహణ"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"అవరోహణ"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g>ని తెరువు"</string>
     <string name="drawer_open" msgid="8071673398187261741">"మూలాలను చూపు"</string>
     <string name="drawer_close" msgid="4263880768630848848">"మూలాలను దాచు"</string>
     <string name="save_error" msgid="8631128801982095782">"పత్రాన్ని సేవ్ చేయడంలో విఫలమైంది"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> అంశాన్ని తొలగిస్తోంది.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"చర్య రద్దు చేయి"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"కాపీ చేయడానికి సిద్ధం చేస్తోంది…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"కుదించడానికి సిద్ధం చేస్తోంది…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"సంగ్రహించడానికి సిద్ధం చేస్తోంది..."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"తరలించడానికి సిద్ధమవుతోంది…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"తొలగించడానికి సిద్ధం చేస్తోంది…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"సిద్ధం చేస్తోంది..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"సిద్ధం చేస్తోంది..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"సిద్ధం చేస్తోంది..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"సిద్ధం చేస్తోంది..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"సిద్ధం చేస్తోంది..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> అంశాలను కాపీ చేయడం సాధ్యపడలేదు</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="STORAGE"><i>^3</i></xliff:g>లో <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>లోని ఫోటోలు మరియు వీడియోలతో సహా మీ డేటా ప్రాప్యతను <xliff:g id="APPNAME"><b>^1</b></xliff:g>కి మంజూరు చేయాలా?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"మళ్లీ అడగవద్దు"</string>
     <string name="allow" msgid="1275746941353040309">"అనుమతించు"</string>
     <string name="deny" msgid="5127201668078153379">"తిరస్కరించు"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"ఆర్కైవ్ చేయి<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g>ని భర్తీ చేయాలా?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"నేపథ్యంలో కొనసాగించు"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఎంచుకోబడ్డాయి</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ఫోన్‌లో తాజా ఫైల్‌లు"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ఫోన్‌లో ఫైల్‌లు"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"ఫోన్‌లోని <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>లోని ఫైల్‌లు"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>లోని ఫైల్‌లు"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>లోని ఫైల్‌లు"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"ఫోన్‌లోని తాజా ఫోటోలు"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"ఫోన్‌లోని ఫోటోలు"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>లోని ఫోటోలు"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>లోని ఫోటోలు"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>లోని ఫోటోలు / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"చిత్రాలు"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"ఆడియో"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"వీడియోలు"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"పత్రాలు"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ఫోల్డర్ పేరు"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"కొత్త పేరు"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g>ని ప్రివ్యూ చేయండి"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"ఇతర యాప్‌లలో ఫైల్స్‌ని బ్రౌజ్ చేయి"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"తెలియనిది"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"కి యాక్సెస్ ఇవ్వు"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\"లో \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\"కి యాక్సెస్ ఇవ్వాలా?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"ఇది ప్రస్తుతం ఈ స్థానం కింద నిల్వ చేయబడి ఉన్న మొత్తం ఫైల్‌లను మరియు భవిష్యత్తులో నిల్వ చేయబోయే కంటెంట్‌ను యాక్సెస్ చేసుకోవడానికి \"<xliff:g id="APPNAME">%1$s</xliff:g>\" యాప్‌కు పూర్తిగా అనుమతిస్తుంది."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ఈ ఫోన్‌లో వెతకండి"</string>
 </resources>
diff --git a/res/values-th/config.xml b/res/values-th/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-th/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index b94205c..ccf6b56 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"แชร์"</string>
     <string name="menu_delete" msgid="1022254131543256626">"ลบ"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"เลือกทั้งหมด"</string>
+    <string name="menu_select" msgid="1366061076507142387">"เลือก"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"จัดเรียงตาม..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"คัดลอกไปยัง…"</string>
     <string name="menu_move" msgid="2310760789561129882">"ย้ายไปที่…"</string>
     <string name="menu_compress" msgid="37539111904724188">"บีบอัด"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"ประเภท"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"ขนาด"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"แก้ไข"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"ชื่อไฟล์ (A ไป Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"ประเภท (A ไป Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"ขนาด (เล็กที่สุดก่อน)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"การแก้ไข (เก่าสุดก่อน)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"ชื่อไฟล์ (Z ไป A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"ประเภท (Z ไป A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"ขนาด (ใหญ่ที่สุดก่อน)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"การแก้ไข (ล่าสุดก่อน)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"จัดเรียงตาม"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"จัดเรียงตาม <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"จำนวนรายการ"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"จากน้อยไปมาก"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"จากมากไปน้อย"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"เปิด <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"แสดงราก"</string>
     <string name="drawer_close" msgid="4263880768630848848">"ซ่อนราก"</string>
     <string name="save_error" msgid="8631128801982095782">"การบันทึกเอกสารล้มเหลว"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">กำลังลบ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"เลิกทำ"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"กำลังเตรียมการคัดลอก…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"กำลังเตรียมบีบอัด…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"เตรียมแตกไฟล์…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"กำลังเตรียมการย้าย…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"กำลังเตรียมลบ…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"กำลังเตรียม..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"กำลังเตรียม..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"กำลังเตรียม..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"กำลังเตรียม..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"กำลังเตรียม..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">ไม่สามารถคัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ในการเข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ใน <xliff:g id="STORAGE"><i>^3</i></xliff:g> ไหม"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ไหม"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงข้อมูลของคุณ รวมถึงรูปภาพและวิดีโอใน <xliff:g id="STORAGE"><i>^2</i></xliff:g> ไหม"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"ไม่ต้องถามอีก"</string>
     <string name="allow" msgid="1275746941353040309">"อนุญาต"</string>
     <string name="deny" msgid="5127201668078153379">"ปฏิเสธ"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"ที่เก็บถาวร<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"เขียนทับ <xliff:g id="NAME">%1$s</xliff:g> ไหม"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"ดำเนินการต่อในพื้นหลัง"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">เลือกไว้ <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
+      <item quantity="one">เลือกไว้ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"ไฟล์ล่าสุดในโทรศัพท์"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"ไฟล์ในโทรศัพท์"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g>ในโทรศัพท์"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"ไฟล์ใน <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"ไฟล์จาก <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"ไฟล์จาก <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"รูปภาพล่าสุดในโทรศัพท์"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"รูปภาพในโทรศัพท์"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"รูปภาพใน <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"รูปภาพจาก <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"รูปภาพจาก <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"รูปภาพ"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"เสียง"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"วิดีโอ"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"เอกสาร"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"ชื่อโฟลเดอร์"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"ชื่อใหม่"</string>
+    <string name="preview_file" msgid="4056622696305432343">"แสดงพรีวิวไฟล์ <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"เรียกดูไฟล์ในแอปอื่นๆ"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"ไม่ระบุชื่อ"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"อนุญาตให้เข้าถึง \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"อนุญาตให้เข้าถึง \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ใน \"<xliff:g id="ROOT">%2$s</xliff:g>\" ใช่ไหม"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"การดำเนินการดังกล่าวจะอนุญาตให้ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" เข้าถึงทุกไฟล์ที่จัดเก็บอยู่ในตำแหน่งนี้ และเนื้อหาอื่นๆ ที่จะจัดเก็บไว้ที่นี่ในอนาคตได้โดยสมบูรณ์"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"ค้นหาโทรศัพท์เครื่องนี้"</string>
 </resources>
diff --git a/res/values-tl/config.xml b/res/values-tl/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-tl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index ac28e52..325d4d0 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Ibahagi"</string>
     <string name="menu_delete" msgid="1022254131543256626">"I-delete"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Piliin lahat"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Piliin"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Pagbukud-bukurin ayon sa..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopyahin sa..."</string>
     <string name="menu_move" msgid="2310760789561129882">"Ilipat sa…"</string>
     <string name="menu_compress" msgid="37539111904724188">"I-compress"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Uri"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Laki"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Binago"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Pangalan ng file (A-Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Uri (A-Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Laki (pinakamaliit muna)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Binago (pinakaluma muna)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Pangalan ng file (Z-A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Uri (Z-A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Laki (pinakamalaki muna)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Binago (pinakabago muna)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Isaayos ayon sa"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Nakaayos ayon sa <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Bilang ng mga item"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Pataas"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Pababa"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Buksan ang <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Ipakita ang mga root"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Itago ang mga root"</string>
     <string name="save_error" msgid="8631128801982095782">"Hindi na-save ang dokumento"</string>
@@ -79,7 +92,7 @@
     <string name="root_type_shortcut" msgid="6059343175525442279">"Mga Shortcut"</string>
     <string name="root_type_device" msgid="1713604128005476585">"Mga Device"</string>
     <string name="root_type_apps" msgid="8646073235029886342">"Higit pang mga app"</string>
-    <string name="empty" msgid="5300254272613103004">"Walang mga item"</string>
+    <string name="empty" msgid="5300254272613103004">"Walang item"</string>
     <string name="no_results" msgid="2371026325236359209">"Walang mga katugma sa %1$s"</string>
     <string name="toast_no_application" msgid="7555319548595113121">"Hindi mabuksan ang file"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Hindi mabuksan ang mga file sa mga archive"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Dine-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na item.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"I-undo"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Naghahanda para sa pagkopya…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Inihahandang i-compress…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Inihahanda para sa pag-extract…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Naghahanda para sa paglilipat…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Naghahanda para sa pag-delete…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Inihahanda..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Inihahanda..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Inihahanda..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Inihahanda..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Inihahanda..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Gusto mo bang bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa directory ng <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Gusto mo bang bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa directory ng <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Gusto mo bang bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa iyong data, kabilang ang mga larawan at video, sa <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Huwag nang tatanunging muli"</string>
     <string name="allow" msgid="1275746941353040309">"Payagan"</string>
     <string name="deny" msgid="5127201668078153379">"Tanggihan"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"I-overwrite ang <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Magpatuloy sa background"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Mga kamakailang file sa telepono"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Mga file sa telepono"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> sa telepono"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Mga file sa <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Mga file mula sa <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Mga file mula sa <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Mga kamakailang larawan sa telepono"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Mga larawan sa telepono"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Mga larawan sa <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Mga larawan mula sa <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Mga larawan mula sa <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Mga Larawan"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Mga Video"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Mga Dokumento"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Pangalan ng folder"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Bagong pangalan"</string>
+    <string name="preview_file" msgid="4056622696305432343">"I-preview ang file na <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"I-browse ang mga file sa iba pang app"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonymous"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Payagan ang access sa \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Payagan ang access sa \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" sa \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Mabibigyang-daan nito ang \"<xliff:g id="APPNAME">%1$s</xliff:g>\" na magkaroon ng ganap na access sa lahat ng file na kasalukuyang naka-store sa ilalim ng lokasyong ito, at anumang content sa hinaharap na naka-store dito."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Maghanap sa teleponong ito"</string>
 </resources>
diff --git a/res/values-tr/config.xml b/res/values-tr/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-tr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 7556431..cdfeef1 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Paylaş"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Sil"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Tümünü seç"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Seç"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sıralama ölçütü..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Klasöre kopyala…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Klasöre taşı..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Sıkıştır"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Tür"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Boyut"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Değiştirilme zamanı"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Dosya adı (A - Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Tür (A - Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Boyut (önce en küçük)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Değiştirilme (önce eski)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Dosya adı (Z - A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Tür (Z - A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Boyut (önce en büyük)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Değiştirilme (önce yeni)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sıralama ölçütü"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sıralama ölçütü: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Ürün sayısı"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Artan"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Azalan"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını aç"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Kök dizinleri göster"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Kök dizinleri sakla"</string>
     <string name="save_error" msgid="8631128801982095782">"Doküman kaydedilemedi"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe siliniyor.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Geri al"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Kopyalamak için hazırlanıyor…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Sıkıştırma için hazırlanıyor…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Çıkarılmaya hazırlanıyor…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Taşıma için hazırlanıyor…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Silmek için hazırlanıyor…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Hazırlanıyor..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Hazırlanıyor..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Hazırlanıyor..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Hazırlanıyor..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Hazırlanıyor..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe kopyalanamadı</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına <xliff:g id="STORAGE"><i>^3</i></xliff:g> depolama alanındaki <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişim izni verilsin mi?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişmek için <xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına izin verilsin mi?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasının, fotoğraflar ve videolar dahil olmak üzere <xliff:g id="STORAGE"><i>^2</i></xliff:g> üzerindeki verilerinize erişmesine izin verilsin mi?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Tekrar sorma"</string>
     <string name="allow" msgid="1275746941353040309">"İzin ver"</string>
     <string name="deny" msgid="5127201668078153379">"Reddet"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arşiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> dosyasının üzerine yazılsın mı?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Arka planda devam et"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe seçildi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe seçildi</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Telefondaki son dosyalar"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Telefondaki dosyalar"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Telefondaki <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazındaki dosyalar"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> dosyaları"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> dosyaları / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Telefondaki son resimler"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Telefondaki resimler"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazındaki resimler"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Resimlerin kaynağı: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> kaynağındaki resimler / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Resimler"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Ses"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videolar"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Dokümanlar"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Klasör adı"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Yeni ad"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> dosyasını önizleyin"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Diğer uygulamalarda dosyalara göz atma"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Adsız"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" dizinine erişime izin ver"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" üzerinde \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" dizinine erişime izin verilsin mi?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" uygulamasının şu anda bu konumda depolanan tüm dosyalara ve ileride burada depolanacak içeriklere tam erişim hakkına sahip olmasını sağlar."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Bu telefonu arayın"</string>
 </resources>
diff --git a/res/values-uk/config.xml b/res/values-uk/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-uk/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index e0d1fb0..018cc6e 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Надіслати"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Видалити"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Вибрати все"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Вибрати"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Сортувати за…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Копіювати в…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Перемістити в…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Стиснути"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Тип"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Розмір"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Змінено"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"назвою файлу (А–Я)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"типом (А–Я)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"розміром (спершу менші)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"змінами (спершу старіші)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"назвою файлу (Я–А)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"типом (Я–А)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"розміром (спершу більші)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"змінами (спершу новіші)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Сортувати за"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Посортовано за <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Кількість елементів"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"За зростанням"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"За спаданням"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Відкрити додаток <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Показати кореневі каталоги"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Сховати кореневі каталоги"</string>
     <string name="save_error" msgid="8631128801982095782">"Не вдалося зберегти документ"</string>
@@ -122,11 +135,11 @@
       <item quantity="other">Видаляються <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Скасувати"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Підготовка до копіювання…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Підготовка до стискання…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Підготовка до отримання…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Підготовка до переміщення…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Підготовка до видалення…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Підготовка…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Підготовка…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Підготовка…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Підготовка…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Підготовка…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> з <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
@@ -204,7 +217,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" на пристрої пам’яті <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\"?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до ваших даних, зокрема до фотографій і відео на пристрої пам’яті <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Не запитувати знову"</string>
     <string name="allow" msgid="1275746941353040309">"Дозволити"</string>
     <string name="deny" msgid="5127201668078153379">"Відхилити"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -248,4 +260,34 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Замінити назву \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Продовжити у фоновому режимі"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="few">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="many">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Останні файли на телефоні"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Файли на телефоні"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> на телефоні"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Файли на пристрої <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Файли зі сховища даних <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Файли зі сховища даних <xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Нещодавні зображення на телефоні"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Зображення на телефоні"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>: зображення"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>: зображення"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>: зображення (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Зображення"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Аудіо"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Відео"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Документи"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Назва папки"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Нова назва"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Переглянути файл \"<xliff:g id="FILENAME">%1$s</xliff:g>\""</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Переглянути файли в інших додатках"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Анонімно"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Дозволити доступ до каталогу \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Дозволити доступ до каталогу \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" з правами \"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Додаток <xliff:g id="APPNAME">%1$s</xliff:g> матиме повний доступ до файлів, які зараз зберігаються в цьому каталозі, і до вмісту, який буде зберігатися тут у майбутньому."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Шукати цей телефон"</string>
 </resources>
diff --git a/res/values-ur/config.xml b/res/values-ur/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-ur/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 2956505..a2098e5 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"اشتراک کریں"</string>
     <string name="menu_delete" msgid="1022254131543256626">"حذف کریں"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"سبھی کو منتخب کریں"</string>
+    <string name="menu_select" msgid="1366061076507142387">"منتخب کریں"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"ترتیب دیں بلحاظ..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"اس میں کاپی کریں…"</string>
     <string name="menu_move" msgid="2310760789561129882">"اس میں منتقل کریں…"</string>
     <string name="menu_compress" msgid="37539111904724188">"کمپریس کریں"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"قسم"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"سائز"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"ترمیم ہوئی"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"‏فائل کا نام (A سے Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"‏قسم (A سے Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"سائز (پہلے سب سے چھوٹا)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"ترمیم شدہ (پہلے قدیم ترین)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"‏فائل کا نام (Z سے A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"‏قسم (Z سے A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"سائز (پہلے سب سے بڑا)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"ترمیم شدہ (پہلے جدید ترین)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"ترتیب دیں بلحاظ"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"بلحاظ <xliff:g id="LABEL">%s</xliff:g> ترتیب شدہ"</string>
     <string name="directory_items" msgid="6645621978998614003">"آئٹمز کی تعداد"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"صعودی"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"نزولی"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> کھولیں"</string>
     <string name="drawer_open" msgid="8071673398187261741">"روٹس دکھائیں"</string>
     <string name="drawer_close" msgid="4263880768630848848">"روٹس کو چھپائیں"</string>
     <string name="save_error" msgid="8631128801982095782">"دستاویز کو محفوظ کرنے میں ناکام ہو گیا۔"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> آئٹم حذف ہو رہا ہے۔</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"کالعدم کریں"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"کاپی کیلئے تیار ہو رہا ہے…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"کمپریس کیلئے تیار ہو رہا ہے…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"فائلیں نکالنے کی تیاری ہو رہی ہے…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"منتقلی کیلئے تیار ہو رہی ہیں…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"حذف کرنے کیلئے تیاری ہو رہی ہے…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"تیار ہو رہا ہے…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"تیار ہو رہا ہے…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"تیار ہو رہا ہے…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"تیار ہو رہا ہے…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"تیار ہو رہا ہے…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> آئٹمز کاپی نہیں ہو سکے</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="STORAGE"><i>^3</i></xliff:g> پر <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی عطا کریں؟"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی دیں؟"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو اپنے ڈیٹا بشمول <xliff:g id="STORAGE"><i>^2</i></xliff:g> پر موجود تصاویر اور ویڈیوز تک رسائی عطا کریں؟"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"دوبارہ مت پوچھیں"</string>
     <string name="allow" msgid="1275746941353040309">"اجازت دیں"</string>
     <string name="deny" msgid="5127201668078153379">"مسترد کریں"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"آرکائیو<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> کو اوور رائٹ کریں؟"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"پس منظر میں جاری رکھیں"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> منتخب کردہ</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> منتخب کردہ</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"فون پر حالیہ فائلز"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"فون میں فائلز"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"فون پر <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> میں فائلز"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> کی جانب سے فائلز"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> کی جانب سے فائلز"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"فون پر موجود حالیہ تصاویر"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"فون پر موجود تصاویر"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> پر موجود تصاویر"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> کی تصاویر"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> کی تصاویر"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"تصاویر"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"آڈیو"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"ویڈیوز"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"دستاویزات"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"فولڈر کا نام"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"نیا نام"</string>
+    <string name="preview_file" msgid="4056622696305432343">"فائل <xliff:g id="FILENAME">%1$s</xliff:g> کا پیش منظر"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"دیگر ایپس میں فائلز کو براؤز کریں"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"گمنام"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" تک رسائی کی اجازت دیں"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"\"<xliff:g id="ROOT">%2$s</xliff:g>\" پر \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" تک رسائی کی اجازت دیں؟"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"یہ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" کو فی الوقت اس مقام کے تحت اسٹور کردہ تمام فائلوں اور یہاں اسٹور کردہ مستقبل کے کسی بھی مواد تک مکمل رسائی کی اجازت دے گی۔"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"یہ فون تلاش کریں"</string>
 </resources>
diff --git a/res/values-uz/config.xml b/res/values-uz/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-uz/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-uz/inspector_strings.xml b/res/values-uz/inspector_strings.xml
index 1a791f3..680c645 100644
--- a/res/values-uz/inspector_strings.xml
+++ b/res/values-uz/inspector_strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="inspector_title" msgid="1924760928091740238">"Ma’lumot"</string>
+    <string name="inspector_title" msgid="1924760928091740238">"Axborot"</string>
     <string name="inspector_load_error" msgid="7522190243413249291">"Fayl haqida ma’lumotni yuklab bo‘lmadi"</string>
     <string name="inspector_debug_section" msgid="2576052661505700421">"Xatoliklarni tuzatish (faqat dasturchilar uchun)"</string>
     <string name="inspector_debug_metadata_section" msgid="5875140675600744846">"RAW fayli meta-axboroti: <xliff:g id="METADATATYPE">%1$s</xliff:g>"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index e221715..8c56175 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="files_label" msgid="771781190045103748">"Fayllar"</string>
-    <string name="downloads_label" msgid="5462789470049501103">"Yuklanishlar"</string>
+    <string name="downloads_label" msgid="5462789470049501103">"Yuklanmalar"</string>
     <!-- no translation found for app_label (8089292432455111409) -->
     <skip />
     <!-- no translation found for launcher_label (799410258349837668) -->
@@ -36,12 +36,14 @@
     <string name="menu_share" msgid="4307140947108068356">"Yuborish"</string>
     <string name="menu_delete" msgid="1022254131543256626">"O‘chirish"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Hammasini belgilash"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Tanlash"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Saralash tartibi…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"Nusxalash…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Ko‘chirib o‘tkazish…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Arxivlash"</string>
     <string name="menu_extract" msgid="8171946945982532262">"Arxivdan chiqarish"</string>
     <string name="menu_rename" msgid="1883113442688817554">"Qayta nomlash"</string>
-    <string name="menu_inspect" msgid="7279855349299446224">"Ma’lumot olish"</string>
+    <string name="menu_inspect" msgid="7279855349299446224">"Axborot olish"</string>
     <string name="menu_view_in_owner" msgid="7228948660557554770">"<xliff:g id="SOURCE">%1$s</xliff:g> orqali ochish"</string>
     <string name="menu_new_window" msgid="2947837751796109126">"Yangi oyna"</string>
     <string name="menu_cut_to_clipboard" msgid="2878752142015026229">"Kesish"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Turi"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Hajmi"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Tahrirlangan"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Nomi (alifbo tartibida)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Alifbo tartibida"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Hajmi (avval kichik)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Tahrir sanasi (avval eski)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Nomi (teskari alifbo)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Teskari alifbo tartibida"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Hajmi (avval katta)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Tahrir sanasi (avval yangi)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Saralash tartibi"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Saralangan: <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Elementlar soni"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"O‘sish bo‘yicha"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Kamayish bo‘yicha"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasini ochish"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Ko‘rsatish"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Berkitish"</string>
     <string name="save_error" msgid="8631128801982095782">"Hujjatni saqlab bo‘lmadi"</string>
@@ -79,7 +92,7 @@
     <string name="root_type_shortcut" msgid="6059343175525442279">"Tezkor tugmalar"</string>
     <string name="root_type_device" msgid="1713604128005476585">"Qurilmalar"</string>
     <string name="root_type_apps" msgid="8646073235029886342">"Boshqa ilovalar"</string>
-    <string name="empty" msgid="5300254272613103004">"Hech narsa yo‘q"</string>
+    <string name="empty" msgid="5300254272613103004">"Hech narsa topilmadi"</string>
     <string name="no_results" msgid="2371026325236359209">"%1$s jildidan topilmadi"</string>
     <string name="toast_no_application" msgid="7555319548595113121">"Faylni ochib bo‘lmadi"</string>
     <string name="toast_view_in_archives_unsupported" msgid="1923221390170964845">"Arxivdagi fayllarni ochib bo‘lmadi"</string>
@@ -112,11 +125,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta element o‘chirib tashlanmoqda.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Bekor qilish"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Nuxsa olishga tayyorgarlik..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Arxivga tayyorlanmoqda…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Tayyorlanmoqda…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Ko‘chirishga tayyorgarlik…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"O‘chirishga tayyorlanmoqda…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Tayyorlanmoqda…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Tayyorlanmoqda…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Tayyorlanmoqda…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Tayyorlanmoqda…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Tayyorlanmoqda…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta elementdan nusxa olib bo‘lmadi</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasining <xliff:g id="STORAGE"><i>^3</i></xliff:g> xotirasidagi “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildiga kirishiga ruxsat berilsinmi?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildidan foydalanishiga ruxsat berilsinmi?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga <xliff:g id="STORAGE"><i>^2</i></xliff:g> xotirasidagi ma’lumotlardan, jumladan, rasmlar va videolardan foydalanishiga ruxsat berilsinmi?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Boshqa so‘ralmasin"</string>
     <string name="allow" msgid="1275746941353040309">"Ruxsat berish"</string>
     <string name="deny" msgid="5127201668078153379">"Rad etish"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"arxiv<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"<xliff:g id="NAME">%1$s</xliff:g> fayli almashtirilsinmi?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Fonda davom ettirish"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta tanlandi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta tanlandi</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Telefonda yaqinda ochilgan fayllar"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Telefondagi fayllar"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"Telefondagi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidagi fayllar"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g> fayllari"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> fayllari (<xliff:g id="SUMMARY">%2$s</xliff:g>)"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Telefondagi oxirgi rasmlar"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Telefondagi rasmlar"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidagi rasmlar"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> rasmlari"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Rasmlar: <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Rasmlar"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Audio"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Videolar"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Hujjatlar"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Jild nomi"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Yangi nom"</string>
+    <string name="preview_file" msgid="4056622696305432343">"<xliff:g id="FILENAME">%1$s</xliff:g> fayliga nazar solish"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Fayllarni boshqa ilovalar orqali topish"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Anonim"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"“<xliff:g id="DIRECTORY">%1$s</xliff:g>” katalogiga ruxsat berilsinmi?"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"“<xliff:g id="ROOT">%2$s</xliff:g>” ichidagi <xliff:g id="DIRECTORY">%1$s</xliff:g> katalogiga ruxsat berilsinmi?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"U “<xliff:g id="APPNAME">%1$s</xliff:g>” ilovasiga hozirda ushbu joydagi barcha mavjud fayllar va keyinchalik shu yerga saqlanadigan fayllardan foydalanishga ruxsat beradi."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Bu telefondan qidirish"</string>
 </resources>
diff --git a/res/values-vi/config.xml b/res/values-vi/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-vi/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 4bce8a3..f163c21 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Chia sẻ"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Xóa"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Chọn tất cả"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Chọn"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Sắp xếp theo..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Sao chép vào…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Chuyển tới..."</string>
     <string name="menu_compress" msgid="37539111904724188">"Nén"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Loại"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Kích thước"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Đã sửa đổi"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Tên tệp (A đến Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Loại (A đến Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Kích thước (nhỏ nhất trước)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Đã sửa đổi (cũ nhất trước)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Tên tệp (Z đến A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Loại (Z đến A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Kích thước (lớn nhất trước)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Đã sửa đổi (mới nhất trước)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Sắp xếp theo"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Sắp xếp theo <xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Số mục"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Tăng dần"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Giảm dần"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Mở <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Hiển thị gốc"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Ẩn gốc"</string>
     <string name="save_error" msgid="8631128801982095782">"Không lưu tài liệu được"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">Đang xóa <xliff:g id="COUNT_0">%1$d</xliff:g> mục.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Hoàn tác"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Đang chuẩn bị sao chép…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Đang chuẩn bị nén…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Đang chuẩn bị giải nén…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Đang chuẩn bị di chuyển…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Đang chuẩn bị xóa…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Đang chuẩn bị…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Đang chuẩn bị…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Đang chuẩn bị…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Đang chuẩn bị…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Đang chuẩn bị…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">Không thể sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> mục</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> trong <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào dữ liệu của bạn, kể cả ảnh và video trên <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Không hỏi lại"</string>
     <string name="allow" msgid="1275746941353040309">"Cho phép"</string>
     <string name="deny" msgid="5127201668078153379">"Từ chối"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,33 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"lưu trữ<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Ghi đè <xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Tiếp tục ở chế độ nền"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">Đã chọn <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Đã chọn <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Tệp gần đây trên điện thoại"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Tệp trên điện thoại"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> trên điện thoại"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Tệp trên <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Tệp từ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Tệp từ <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Hình ảnh gần đây trên điện thoại"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Hình ảnh trên điện thoại"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Hình ảnh trên <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Hình ảnh từ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Hình ảnh từ <xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Hình ảnh"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Âm thanh"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Video"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Tài liệu"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Tên thư mục"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Tên mới"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Xem trước tệp <xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Duyệt qua tệp trong các ứng dụng khác"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Ẩn danh"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Cho phép truy cập vào \"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <!-- no translation found for open_tree_dialog_title (8429465292253532274) -->
+    <skip />
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Điều này sẽ cho phép \"<xliff:g id="APPNAME">%1$s</xliff:g>\" có quyền truy cập đầy đủ vào tất cả các tệp hiện được lưu trữ ở vị trí này và mọi nội dung sau này sẽ lưu trữ tại đây."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Tìm kiếm điện thoại này"</string>
 </resources>
diff --git a/res/values-zh-rCN/config.xml b/res/values-zh-rCN/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-zh-rCN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index cb990eb..8b654e0 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"分享"</string>
     <string name="menu_delete" msgid="1022254131543256626">"删除"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"全选"</string>
+    <string name="menu_select" msgid="1366061076507142387">"选择"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"排序依据…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"复制到…"</string>
     <string name="menu_move" msgid="2310760789561129882">"移动到…"</string>
     <string name="menu_compress" msgid="37539111904724188">"压缩"</string>
@@ -48,8 +50,8 @@
     <string name="menu_copy_to_clipboard" msgid="5064081159073330776">"复制"</string>
     <string name="menu_paste_from_clipboard" msgid="360947260414135827">"粘贴"</string>
     <string name="menu_paste_into_folder" msgid="8000644546983240101">"粘贴到文件夹中"</string>
-    <string name="menu_advanced_show" msgid="7558626506462906726">"显示内部存储设备"</string>
-    <string name="menu_advanced_hide" msgid="6488381508009246334">"隐藏内部存储设备"</string>
+    <string name="menu_advanced_show" msgid="7558626506462906726">"显示内部存储空间"</string>
+    <string name="menu_advanced_hide" msgid="6488381508009246334">"隐藏内部存储空间"</string>
     <string name="button_select" msgid="240863497069321364">"选择"</string>
     <string name="button_copy" msgid="8219059853840996027">"复制"</string>
     <string name="button_compress" msgid="8951561310857223966">"压缩"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"类型"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"大小"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"上次修改时间"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"文件名(从 A 到 Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"类型(从 A 到 Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"大小(从小到大)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"修改日期(从旧到新)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"文件名(从 Z 到 A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"类型(从 Z 到 A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"大小(从大到小)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"修改日期(从新到旧)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"排序方式"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"按<xliff:g id="LABEL">%s</xliff:g>排序"</string>
     <string name="directory_items" msgid="6645621978998614003">"项数"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"升序"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"降序"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"打开<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"显示根目录"</string>
     <string name="drawer_close" msgid="4263880768630848848">"隐藏根目录"</string>
     <string name="save_error" msgid="8631128801982095782">"无法保存文档"</string>
@@ -92,8 +105,8 @@
     <string name="delete_notification_title" msgid="2512757431856830792">"正在删除文件"</string>
     <string name="copy_remaining" msgid="5390517377265177727">"剩余时间:<xliff:g id="DURATION">%s</xliff:g>"</string>
     <plurals name="copy_begin" formatted="false" msgid="151184708996738192">
-      <item quantity="other">正在复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
-      <item quantity="one">正在复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
+      <item quantity="other">正在复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 项。</item>
+      <item quantity="one">正在复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 项。</item>
     </plurals>
     <plurals name="compress_begin" formatted="false" msgid="3534158317098678895">
       <item quantity="other">正在压缩 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
@@ -104,19 +117,19 @@
       <item quantity="one">正在解压 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
     </plurals>
     <plurals name="move_begin" formatted="false" msgid="1464229874265756956">
-      <item quantity="other">正在移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
-      <item quantity="one">正在移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
+      <item quantity="other">正在移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 项。</item>
+      <item quantity="one">正在移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 项。</item>
     </plurals>
     <plurals name="deleting" formatted="false" msgid="1729138001178158901">
-      <item quantity="other">正在删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
-      <item quantity="one">正在删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
+      <item quantity="other">正在删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 项。</item>
+      <item quantity="one">正在删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 项。</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"撤消"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"正在准备复制…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"正准备压缩…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"正在准备解压缩…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"正在准备移动…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"正在准备删除…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"正在准备…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"正在准备…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"正在准备…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"正在准备…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"正在准备…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">无法复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问<xliff:g id="STORAGE"><i>^3</i></xliff:g>上的“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问您<xliff:g id="STORAGE"><i>^2</i></xliff:g>上的数据(包括照片和视频)吗?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"不再询问"</string>
     <string name="allow" msgid="1275746941353040309">"允许"</string>
     <string name="deny" msgid="5127201668078153379">"拒绝"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"归档<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"要覆盖 <xliff:g id="NAME">%1$s</xliff:g> 吗?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"继续在后台执行"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">已选择 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
+      <item quantity="one">已选择 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"最近在手机上使用过的文件"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"手机上的文件"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"手机上的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>上的文件"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"<xliff:g id="LABEL">%1$s</xliff:g>中的文件"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g>中的文件/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"手机上的近期图片"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"手机上的图片"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>上的图片"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"来自<xliff:g id="LABEL">%1$s</xliff:g>的图片"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"来自<xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g> 的图片"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"图片"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"音频"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"视频"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"文档"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"文件夹名称"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"新名称"</string>
+    <string name="preview_file" msgid="4056622696305432343">"预览“<xliff:g id="FILENAME">%1$s</xliff:g>”文件"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"浏览其他应用中的文件"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"匿名"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"允许访问“<xliff:g id="DIRECTORY">%1$s</xliff:g>”"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"允许访问“<xliff:g id="ROOT">%2$s</xliff:g>”上的“<xliff:g id="DIRECTORY">%1$s</xliff:g>”吗?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"它将允许“<xliff:g id="APPNAME">%1$s</xliff:g>”拥有对以下内容的完整访问权限:目前存储在此位置下的所有文件,以及日后存储在此处的任何内容。"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"搜索此手机"</string>
 </resources>
diff --git a/res/values-zh-rHK/config.xml b/res/values-zh-rHK/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-zh-rHK/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 67d3e6a..e80dfc5 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"分享"</string>
     <string name="menu_delete" msgid="1022254131543256626">"刪除"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"全選"</string>
+    <string name="menu_select" msgid="1366061076507142387">"選取"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"排序方式…"</string>
     <string name="menu_copy" msgid="7404820171352314754">"複製到…"</string>
     <string name="menu_move" msgid="2310760789561129882">"移至…"</string>
     <string name="menu_compress" msgid="37539111904724188">"壓縮"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"類型"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"大小"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"上次修改時間"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"檔案名稱 (A 至 Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"類型 (A 至 Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"大小 (由小至大)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"修改日期 (由舊至新)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"檔案名稱 (Z 至 A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"類型 (Z 至 A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"大小 (由大至小)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"修改日期 (由新至舊)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"排序方式"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"已按<xliff:g id="LABEL">%s</xliff:g> 排序"</string>
     <string name="directory_items" msgid="6645621978998614003">"項目數量"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"遞增"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"遞減"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
     <string name="drawer_open" msgid="8071673398187261741">"顯示根目錄"</string>
     <string name="drawer_close" msgid="4263880768630848848">"隱藏根目錄"</string>
     <string name="save_error" msgid="8631128801982095782">"無法儲存文件"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">正在刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目。</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"復原"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"正在準備複製…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"正在準備壓縮檔案…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"正在準備解壓縮檔案…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"正在準備移動…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"正在準備刪除…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"正在準備…"</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"正在準備…"</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"正在準備…"</string>
+    <string name="move_preparing" msgid="6504239656430530761">"正在準備…"</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"正在準備…"</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目。</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄存取權嗎?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄的存取權嗎?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的相片和影片等資料的存取權嗎?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"不要再問我"</string>
     <string name="allow" msgid="1275746941353040309">"允許"</string>
     <string name="deny" msgid="5127201668078153379">"拒絕"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"要覆寫「<xliff:g id="NAME">%1$s</xliff:g>」嗎?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"繼續在背景執行"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+      <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"手機上的最近檔案"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"手機上的檔案"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"手機上的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g>上的檔案"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"來自<xliff:g id="LABEL">%1$s</xliff:g>的檔案"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"來自<xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g> 的檔案"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"手機上最近的圖片"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"手機上的圖片"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g>上的圖片"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g>中的圖片"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g>/<xliff:g id="SUMMARY">%2$s</xliff:g> 中的圖片"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"圖片"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"音訊"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"影片"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"文件"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"資料夾名稱"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"新名稱"</string>
+    <string name="preview_file" msgid="4056622696305432343">"預覽 <xliff:g id="FILENAME">%1$s</xliff:g> 檔案"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"透過其他應用程式瀏覽檔案"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"匿名"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"允許存取「<xliff:g id="DIRECTORY">%1$s</xliff:g>」"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"要允許存取「<xliff:g id="ROOT">%2$s</xliff:g>」的「<xliff:g id="DIRECTORY">%1$s</xliff:g>」嗎?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"這項操作將允許「<xliff:g id="APPNAME">%1$s</xliff:g>」完整存取目前儲存在此位置的所有檔案,以及任何未來在此儲存的內容。"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"搜尋這部手機"</string>
 </resources>
diff --git a/res/values-zh-rTW/config.xml b/res/values-zh-rTW/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-zh-rTW/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 284a5ff..6d7e28f 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"分享"</string>
     <string name="menu_delete" msgid="1022254131543256626">"刪除"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"全選"</string>
+    <string name="menu_select" msgid="1366061076507142387">"選取"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"排序依據..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"複製到…"</string>
     <string name="menu_move" msgid="2310760789561129882">"移至…"</string>
     <string name="menu_compress" msgid="37539111904724188">"壓縮"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"類型"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"大小"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"上次修改時間"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"檔案名稱 (A 到 Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"類型 (A 到 Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"大小 (由小到大)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"修改日期 (由舊到新)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"檔案名稱 (Z 到 A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"類型 (Z 到 A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"大小 (由大到小)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"修改日期 (由新到舊)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"排序依據"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"依<xliff:g id="LABEL">%s</xliff:g> 排序"</string>
     <string name="directory_items" msgid="6645621978998614003">"項目數量"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"遞增"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"遞減"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
     <string name="drawer_open" msgid="8071673398187261741">"顯示根目錄"</string>
     <string name="drawer_close" msgid="4263880768630848848">"隱藏根目錄"</string>
     <string name="save_error" msgid="8631128801982095782">"無法儲存文件"</string>
@@ -112,11 +125,11 @@
       <item quantity="one">正在刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目。</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"復原"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"正在準備複製…"</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"正在準備壓縮…"</string>
-    <string name="extract_preparing" msgid="58266275455027829">"正在準備解壓縮檔案…"</string>
-    <string name="move_preparing" msgid="8742573245485449429">"正在準備移動…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"正在準備刪除…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"準備中..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"準備中..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"準備中..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"準備中..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"準備中..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的資料 (包括相片和影片) 嗎?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"不要再詢問"</string>
     <string name="allow" msgid="1275746941353040309">"允許"</string>
     <string name="deny" msgid="5127201668078153379">"拒絕"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"要覆寫「<xliff:g id="NAME">%1$s</xliff:g>」嗎?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"繼續在背景執行"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+      <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"最近在手機上使用過的檔案"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"手機中的檔案"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"手機中的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"<xliff:g id="DEVICE">%1$s</xliff:g> 中的檔案"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"「<xliff:g id="LABEL">%1$s</xliff:g>」中的檔案"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"「<xliff:g id="LABEL">%1$s</xliff:g>」中的檔案/<xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"手機上的近期圖片"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"手機上的圖片"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> 上的圖片"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"來自「<xliff:g id="LABEL">%1$s</xliff:g>」的圖片"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"來自「<xliff:g id="LABEL">%1$s</xliff:g>」/<xliff:g id="SUMMARY">%2$s</xliff:g> 的圖片"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"圖片"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"音訊"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"影片"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"文件"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"資料夾名稱"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"新名稱"</string>
+    <string name="preview_file" msgid="4056622696305432343">"預覽 <xliff:g id="FILENAME">%1$s</xliff:g> 檔案"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"瀏覽其他應用程式中的檔案"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"匿名"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"允許存取「<xliff:g id="DIRECTORY">%1$s</xliff:g>」"</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"要允許存取「<xliff:g id="ROOT">%2$s</xliff:g>」上的「<xliff:g id="DIRECTORY">%1$s</xliff:g>」嗎?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"這麼做會允許「<xliff:g id="APPNAME">%1$s</xliff:g>」存取所有儲存在這個位置的檔案,以及未來儲存於此的內容。"</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"搜尋這支手機"</string>
 </resources>
diff --git a/res/values-zu/config.xml b/res/values-zu/config.xml
deleted file mode 100644
index 843a8aa..0000000
--- a/res/values-zu/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 3109dc0..67b7554 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -36,6 +36,8 @@
     <string name="menu_share" msgid="4307140947108068356">"Yabelana"</string>
     <string name="menu_delete" msgid="1022254131543256626">"Susa"</string>
     <string name="menu_select_all" msgid="7600576812185570403">"Khetha konke"</string>
+    <string name="menu_select" msgid="1366061076507142387">"Khetha"</string>
+    <string name="menu_sort" msgid="3362419226163725275">"Hlunga nge..."</string>
     <string name="menu_copy" msgid="7404820171352314754">"Kopishela ku…"</string>
     <string name="menu_move" msgid="2310760789561129882">"Hambisa ku…"</string>
     <string name="menu_compress" msgid="37539111904724188">"Cindezela"</string>
@@ -65,9 +67,20 @@
     <string name="sort_dimension_file_type" msgid="5779709622922085381">"Uhlobo"</string>
     <string name="sort_dimension_size" msgid="2190547351159472884">"Usayizi"</string>
     <string name="sort_dimension_date" msgid="4231005651895254033">"Kulungisiwe"</string>
+    <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"Igama lefayela (A ukuya ku-Z)"</string>
+    <string name="sort_dimension_file_type_ascending" msgid="3466973933402894292">"Uhlobo (A ukuya ku-Z)"</string>
+    <string name="sort_dimension_size_ascending" msgid="2617359017800057762">"Usayizi (encane kakhulu kuqala)"</string>
+    <string name="sort_dimension_date_ascending" msgid="7920068979386920559">"Iguquliwe (endala kakhulu kuqala)"</string>
+    <string name="sort_dimension_name_descending" msgid="1514525521100423342">"Igama lefayela (Z ukuya ku-A)"</string>
+    <string name="sort_dimension_file_type_descending" msgid="3344796059784511100">"Uhlobo (Z ukuya ku-A)"</string>
+    <string name="sort_dimension_size_descending" msgid="2367030017597348938">"Usayizi (enkulu kakhulu kuqala)"</string>
+    <string name="sort_dimension_date_descending" msgid="5466839955763127113">"Iguquliwe (entsha kakhulu kuqala)"</string>
+    <string name="sort_dimension_dialog_title" msgid="3048641573962982157">"Hlunga nge-"</string>
+    <string name="sort_dimension_button_title" msgid="1898606989130896126">"Kuhlungwe nge-<xliff:g id="LABEL">%s</xliff:g>"</string>
     <string name="directory_items" msgid="6645621978998614003">"Inombolo yezinto"</string>
     <string name="sort_direction_ascending" msgid="5882787683763248102">"Iyanyuka"</string>
     <string name="sort_direction_descending" msgid="1729187589765894076">"Iyehla"</string>
+    <string name="open_external_app" msgid="7107920381038980086">"Vula i-<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="drawer_open" msgid="8071673398187261741">"Bonisa izimpande"</string>
     <string name="drawer_close" msgid="4263880768630848848">"Fihla izimpande"</string>
     <string name="save_error" msgid="8631128801982095782">"Yehlulekile ukulondoloza idokhumenti"</string>
@@ -112,11 +125,11 @@
       <item quantity="other">Isusa izinto ezingu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
     </plurals>
     <string name="undo" msgid="2902438994196400565">"Hlehlisa"</string>
-    <string name="copy_preparing" msgid="5326063807006898223">"Ilungiselela ukukopisha..."</string>
-    <string name="compress_preparing" msgid="6650018601382062672">"Ilungiselela ukucindezela..."</string>
-    <string name="extract_preparing" msgid="58266275455027829">"Ilungiselela ukukhipha..."</string>
-    <string name="move_preparing" msgid="8742573245485449429">"Ilungiselela ukuhambisa…"</string>
-    <string name="delete_preparing" msgid="6513863752916028147">"Ilungiselela ukususa…"</string>
+    <string name="copy_preparing" msgid="4759516490222449324">"Iyalungiselela..."</string>
+    <string name="compress_preparing" msgid="7401605598969019696">"Iyalungiselela..."</string>
+    <string name="extract_preparing" msgid="4796626960061745796">"Iyalungiselela..."</string>
+    <string name="move_preparing" msgid="6504239656430530761">"Iyalungiselela..."</string>
+    <string name="delete_preparing" msgid="7339349837842802508">"Iyalungiselela..."</string>
     <string name="delete_progress" msgid="2627631054702306423">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="3188432450429390963">
       <item quantity="one">Ayikwazanga ukukopisha izinto ezingu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
@@ -172,7 +185,6 @@
     <string name="open_external_dialog_request" msgid="8173558471322861268">"Nika i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela ekuqondiseni kwe-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ku-<xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
     <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"Nika ukufinyelela kwe-<xliff:g id="APPNAME"><b>^1</b></xliff:g> kwinkomba ye-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
     <string name="open_external_dialog_root_request" msgid="6776729293982633">"Nikeza i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela kudatha yakho, okufaka izithombe namavidiyo, ku-<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
-    <string name="never_ask_again" msgid="525908236522201138">"Ungaphindi ubuze"</string>
     <string name="allow" msgid="1275746941353040309">"Vumela"</string>
     <string name="deny" msgid="5127201668078153379">"Phika"</string>
     <plurals name="elements_selected" formatted="false" msgid="4448165978637163692">
@@ -206,4 +218,32 @@
     <string name="new_archive_file_name" msgid="1604650338077249838">"ingobo yomlando<xliff:g id="EXTENSION">%s</xliff:g>"</string>
     <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Faka ngaphezulu i-<xliff:g id="NAME">%1$s</xliff:g>?"</string>
     <string name="continue_in_background" msgid="1974214559047793331">"Qhubeka ngemuva"</string>
+    <plurals name="selected_count" formatted="false" msgid="7555250236512981129">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
+    </plurals>
+    <string name="root_info_header_recent" msgid="8754386597210017725">"Amafayela wakamuva efonini"</string>
+    <string name="root_info_header_global_search" msgid="9099308729787003373">"Amafayela efonini"</string>
+    <string name="root_info_header_media" msgid="2774453755906260852">"<xliff:g id="LABEL">%1$s</xliff:g> efonini"</string>
+    <string name="root_info_header_storage" msgid="2989014130584927442">"Amafayela ku-<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app" msgid="2125422047558420885">"Amafayela kusuka ku-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"Amafayela kusuka ku-<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="root_info_header_image_recent" msgid="6252335619444758201">"Izithombe zakamuva kufoni"</string>
+    <string name="root_info_header_image_global_search" msgid="7945533325610533016">"Izithombe ezikufoni"</string>
+    <string name="root_info_header_image_storage" msgid="5086740886360075930">"Izithombe ku-<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app" msgid="4858114210851525359">"Izithombe kusukela ku-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"Izithombe kusukela ku-<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g>"</string>
+    <string name="chip_title_images" msgid="7838299046109841015">"Izithombe"</string>
+    <string name="chip_title_audio" msgid="1032801828748235436">"Umsindo"</string>
+    <string name="chip_title_videos" msgid="7011260091979776447">"Amavidiyo"</string>
+    <string name="chip_title_documents" msgid="7432457563000753983">"Amadokhumenti"</string>
+    <string name="input_hint_new_folder" msgid="479672411219725677">"Igama lefolda"</string>
+    <string name="input_hint_rename" msgid="8390711744270994452">"Igama elisha"</string>
+    <string name="preview_file" msgid="4056622696305432343">"Buka kuqala ifayela le-<xliff:g id="FILENAME">%1$s</xliff:g>"</string>
+    <string name="apps_row_title" msgid="3340490016663092925">"Phequlula amafayela kwezinye izinhlelo zokusebenza"</string>
+    <string name="anonymous_application" msgid="7633027057951625862">"Okungaziwa"</string>
+    <string name="open_tree_button" msgid="19992834788135845">"Vumela ukufinyelela ku-\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\""</string>
+    <string name="open_tree_dialog_title" msgid="6978383241897450134">"Vumela ukufinyelela ku-\"<xliff:g id="DIRECTORY">%1$s</xliff:g>\" ku-\"<xliff:g id="ROOT">%2$s</xliff:g>\"?"</string>
+    <string name="open_tree_dialog_message" msgid="8545093618524340168">"Izovumela i-\"<xliff:g id="APPNAME">%1$s</xliff:g>\" ukuze inikeze ukufinyelela okugcwele kuwo wonke amafayela manje agcinwe ngaphansi kwale ndawo, futhi noma ikuphi okuqukethwe okuzayo kuzogcinwa lapha."</string>
+    <string name="search_bar_hint" msgid="4517366509897977321">"Sesha le foni"</string>
 </resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index b4c0812..dcebd0a 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -14,11 +14,21 @@
      limitations under the License.
 -->
 <resources>
-    <declare-styleable name="HighlightedItemView">
-        <attr name="state_highlighted" format="boolean"/>
-    </declare-styleable>
+
     <declare-styleable name="DropBadgeView">
         <attr name="state_reject_drop" format="boolean"/>
         <attr name="state_copy" format="boolean"/>
     </declare-styleable>
+
+    <declare-styleable name="GridItem">
+        <attr name="gridItemTint" format="reference" />
+        <attr name="gridItemColor" format="reference" />
+        <attr name="gridItemSelectedColor" format="reference" />
+        <attr name="gridItemDisableColor" format="reference" />
+    </declare-styleable>
+
+    <declare-styleable name="HighlightedItemView">
+        <attr name="state_highlighted" format="boolean"/>
+    </declare-styleable>
+
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index c500261..a34f09d 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -18,67 +18,27 @@
     <!-- This is the window background, but also the background for anything
          else that needs to manually declare a background matching the "default"
          app background (e.g. the drawer overlay). -->
-    <color name="window_background">#fff1f1f1</color>
-    <color name="drawer_background">#fff1f1f1</color>
-    <color name="drawer_border">#ffd4d4d4</color>
-    <color name="directory_background">#fff7f7f7</color>
+
+    <color name="app_background_color">@android:color/white</color>
+    <color name="background_floating">@android:color/white</color>
+    <color name="nav_bar_translucent">#99FFFFFF</color>
+
+    <color name="primary">#1E88E5</color> <!-- Blue 600 -->
+    <color name="secondary">#E3F2FD</color> <!-- Blue 50 -->
+    <color name="hairline">#E0E0E0</color> <!-- Gray 300 -->
+
+    <color name="chip_background_disable_color">#fff1f3f4</color>
     <color name="menu_search_background">@android:color/transparent</color>
-
-    <color name="primary_dark">#ff254FAE</color>
-    <color name="primary">@color/tool_bar_color</color>
-    <color name="accent">@color/tool_bar_color</color>
-    <color name="accent_dark">@*android:color/accent_device_default_dark</color>
-
-    <color name="text_cursor">@*android:color/white</color>
-    <color name="text_handle">#FF82B1FF</color>     <!--Blue A100-->
-    <color name="text_highlight">#FF82B1FF</color>  <!--Blue A100-->
+    <color name="item_breadcrumb_background_hovered">#1affffff</color>
+    <color name="item_drag_shadow_background">@android:color/white</color>
+    <color name="item_drag_shadow_container_background">@android:color/transparent</color>
+    <color name="tool_bar_gradient_max">#7f000000</color>
 
     <color name="band_select_background">#88ffffff</color>
     <color name="band_select_border">#44000000</color>
 
-    <color name="root_title_color">#de000000</color>
-    <color name="root_activated_color">@*android:color/Blue_700</color>
-    <color name="root_details_color">#8a000000</color>
-    <color name="root_focus_color">#ffe0e0e0</color>
-
-    <color name="item_hover_color">#ffe0e0e0</color>
-
-    <color name="sort_widget_text_color">#de000000</color>
-
-    <color name="root_icon_color">#ff5a5a5a</color>
-    <item name="root_icon_disabled_alpha" format="float" type="dimen">@*android:dimen/disabled_alpha_material_light</item>
-    <color name="doc_icon_color">#ff5a5a5a</color>
-    <color name="tool_bar_color">#ff1A73E8</color>
-
-    <!-- TODO: Would be nice to move this to a color-set, but not sure how to support animation -->
-    <color name="item_doc_title">#ff333333</color>
-    <color name="item_doc_title_disabled">@*android:color/secondary_text_default_material_light</color>
-    <color name="item_doc_details">#ff333333</color>
-    <color name="item_doc_background">@*android:color/white</color>
-    <color name="item_doc_background_disabled">#fff4f4f4</color>
-    <color name="item_doc_background_selected">#4d3367d6</color>
-    <color name="item_breadcrumb_background_hovered">#1affffff</color>
-    <color name="item_doc_droppable_background">#ffe8f0fb</color>
-    <color name="item_doc_not_droppable_background">#ffe0e0e0</color>
-    <color name="item_grid_tint">@*android:color/Blue_700</color>
-
-    <color name="item_drag_shadow_background">@*android:color/white</color>
-    <color name="item_drag_shadow_container_background">@*android:color/transparent</color>
-
     <color name="downloads_icon_background">#ff4688f2</color>
     <color name="app_icon_background">#ff4688f2</color>
     <color name="shortcut_foreground">#ff3367d6</color>
     <color name="shortcut_background">#fff5f5f5</color>
-
-    <color name="dialog_title">@*android:color/primary_text_default_material_light</color>
-
-    <color name="scroll_thumb_pressed">#ff8c8c8c</color>
-    <color name="scroll_thumb">#ffbebebe</color>
-    <color name="scroll_track">#fff0f0f0</color>
-
-    <color name="inspector_value">#ff939393</color>
-    <color name="inspector_link">#6633b5e5</color>
-    <color name="inspector_section_title">#ff939393</color>
-    <color name="inspector_section_divider">#E0E0E0</color>
-    <color name="inspector_title_background">#40000000</color>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 8e3a943..bb1af22 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -28,7 +28,13 @@
          layouts we reduce this to an input-box adjacent to menu actions. -->
     <bool name="full_bar_search_view">true</bool>
 
+    <!-- Indicates if showing as search bar design -->
+    <bool name="show_search_bar">false</bool>
+
     <string name="default_root_uri" translatable="false">content://com.android.providers.downloads.documents/root/downloads</string>
+    <!-- The value is used in sorting process on Drawer menu. If the root's package name
+     start with it, the item will have higher order than others.-->
+    <string name="preferred_root_package" translatable="false">com.android.shell</string>
 
     <string name="datetime_format_12" translatable="false">MMM dd, yyyy, h:mm a</string>
     <string name="datetime_format_24" translatable="false">MMM dd, yyyy, H:mm</string>
@@ -53,11 +59,22 @@
     <bool name="feature_virtual_files_sharing">true</bool>
     <bool name="feature_inspector">true</bool>
     <bool name="feature_debug_mode">false</bool>
+    <!-- If this value is true, the default root on action browse will be the root from
+    "default_root_uri". Otherwise, the default root will be the recent root.-->
+    <bool name="feature_default_root_in_browse">false</bool>
 
     <!-- Indicates if internal storage is shown as default or not. -->
     <bool name="config_default_show_device_root">false</bool>
 
+    <!-- Whether to show capitalize string on Button -->
+    <bool name="config_button_all_caps">true</bool>
+
     <!-- This option allows us to hide the Files app icon from launcher on Android Go device.
     Android Go device will have Files Go app for file management. -->
     <bool name="is_launcher_enabled">true</bool>
+
+    <string name="scrolling_behavior" translatable="false">com.android.documentsui.ui.SearchBarScrollingViewBehavior</string>
+
+    <!-- The maximum record of search history. -->
+    <integer name="config_maximum_search_history">200</integer>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b720c33..67afcbb 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -15,12 +15,20 @@
 -->
 
 <resources>
-    <dimen name="grid_container_padding">10dp</dimen>
+    <!-- Material design rounded radius -->
+    <dimen name="material_round_radius">2dp</dimen>
+
+    <dimen name="grid_container_padding">20dp</dimen>
     <dimen name="list_container_padding">0dp</dimen>
     <dimen name="icon_size">40dp</dimen>
+    <dimen name="button_touch_size">48dp</dimen>
     <dimen name="root_icon_size">24dp</dimen>
     <dimen name="root_icon_margin">0dp</dimen>
+    <dimen name="root_spacer_padding">0dp</dimen>
+    <dimen name="root_action_icon_size">18dp</dimen>
+    <dimen name="root_icon_disabled_alpha">?android:attr/disabledAlpha</dimen>
     <dimen name="check_icon_size">30dp</dimen>
+    <dimen name="zoom_icon_size">24dp</dimen>
     <dimen name="list_item_thumbnail_size">40dp</dimen>
     <dimen name="grid_item_icon_size">30dp</dimen>
     <dimen name="progress_bar_height">4dp</dimen>
@@ -31,14 +39,17 @@
     <dimen name="grid_item_margin">6dp</dimen>
     <dimen name="grid_padding_horiz">4dp</dimen>
     <dimen name="grid_padding_vert">4dp</dimen>
+    <dimen name="list_item_width">72dp</dimen>
     <dimen name="list_item_height">72dp</dimen>
     <dimen name="list_item_padding">16dp</dimen>
+    <dimen name="list_item_icon_padding">16dp</dimen>
     <dimen name="breadcrumb_item_padding">8dp</dimen>
     <dimen name="breadcrumb_item_height">36dp</dimen>
     <dimen name="list_divider_inset">72dp</dimen>
     <dimen name="dir_elevation">8dp</dimen>
     <dimen name="drag_shadow_size">120dp</dimen>
     <dimen name="grid_item_elevation">2dp</dimen>
+    <dimen name="grid_item_radius">2dp</dimen>
     <dimen name="max_drawer_width">280dp</dimen>
 
     <dimen name="drawer_edge_width">12dp</dimen>
@@ -52,7 +63,7 @@
     <dimen name="doc_header_height">60dp</dimen>
 
     <dimen name="dropdown_sort_widget_margin">12dp</dimen>
-    <dimen name="dropdown_sort_widget_size">48dp</dimen>
+    <dimen name="dropdown_sort_widget_size">54dp</dimen>
     <dimen name="dropdown_sort_text_size">18sp</dimen>
 
     <dimen name="drop_icon_height">14dp</dimen>
@@ -65,11 +76,46 @@
     <dimen name="fastscroll_margin">0dp</dimen>
 
     <dimen name="bottom_bar_height">56dp</dimen>
-    <dimen name="bottom_bar_padding_end">10dp</dimen>
-    <dimen name="bottom_bar_negative_button_width">88.5dp</dimen>
-    <dimen name="bottom_bar_positive_button_margin_start">8dp</dimen>
-    <dimen name="bottom_bar_positive_button_width">73dp</dimen>
-    <dimen name="bottom_bar_positive_button_elevation">2dp</dimen>
+    <dimen name="bottom_bar_padding">10dp</dimen>
+    <dimen name="bottom_bar_button_height">36dip</dimen>
+    <dimen name="bottom_bar_button_horizontal_padding">24dp</dimen>
+    <dimen name="bottom_bar_button_corner_radius">4dp</dimen>
 
-    <dimen name="inspector_header_height">250dp</dimen>
+    <dimen name="inspector_header_height">280dp</dimen>
+
+    <dimen name="root_info_header_height">60dp</dimen>
+    <dimen name="root_info_header_horizontal_padding">24dp</dimen>
+
+    <dimen name="search_chip_group_margin">8dp</dimen>
+    <dimen name="search_chip_spacing">8dp</dimen>
+    <dimen name="search_chip_icon_padding">4dp</dimen>
+    <dimen name="search_chip_radius">16dp</dimen>
+
+    <dimen name="dialog_content_padding_top">18dp</dimen>
+    <dimen name="dialog_content_padding_bottom">24dp</dimen>
+
+    <dimen name="apps_row_title_height">48dp</dimen>
+    <dimen name="apps_row_title_padding_start">24dp</dimen>
+    <dimen name="apps_row_item_width">92dp</dimen>
+    <dimen name="apps_row_item_height">82dp</dimen>
+    <dimen name="apps_row_app_icon_size">32dp</dimen>
+    <dimen name="apps_row_app_icon_margin_horizontal">30dp</dimen>
+    <dimen name="apps_row_app_icon_margin_top">6dp</dimen>
+    <dimen name="apps_row_app_icon_margin_bottom">10dp</dimen>
+    <dimen name="apps_row_exit_icon_size">12dp</dimen>
+    <dimen name="apps_row_exit_icon_margin_top">2dp</dimen>
+    <dimen name="apps_row_exit_icon_margin_bottom">6dp</dimen>
+    <dimen name="apps_row_item_text_margin_horizontal">8dp</dimen>
+
+    <dimen name="search_bar_radius">8dp</dimen>
+    <dimen name="search_bar_background_margin_start">0dp</dimen>
+    <dimen name="search_bar_background_margin_end">0dp</dimen>
+    <dimen name="search_bar_margin">8dp</dimen>
+    <dimen name="search_bar_text_size">16dp</dimen>
+    <dimen name="action_bar_size">48dp</dimen>
+    <!--This value should equal actionBarSize + (2 x search_bar_margin)-->
+    <dimen name="action_bar_space_height">64dp</dimen>
+    <dimen name="action_bar_space_margin">@dimen/action_bar_space_height</dimen>
+
+    <dimen name="refresh_icon_range">64dp</dimen>
 </resources>
diff --git a/res/values/drawables.xml b/res/values/drawables.xml
index 3beac4e..c0575e0 100644
--- a/res/values/drawables.xml
+++ b/res/values/drawables.xml
@@ -17,11 +17,4 @@
 <resources>
     <item name="app_icon" type="drawable">@mipmap/ic_app_icon</item>
     <item name="launcher_icon" type="drawable">@mipmap/ic_app_icon</item>
-    <item name="image_root_icon" type="drawable">@*android:drawable/ic_doc_image</item>
-    <item name="video_root_icon" type="drawable">@*android:drawable/ic_doc_video</item>
-    <item name="audio_root_icon" type="drawable">@*android:drawable/ic_doc_audio</item>
-    <item name="generic_doc_icon" type="drawable">@*android:drawable/ic_doc_generic</item>
-    <item name="search_text_select_handle_left" type="drawable">@*android:drawable/text_select_handle_left_mtrl_alpha</item>
-    <item name="search_text_select_handle_right" type="drawable">@*android:drawable/text_select_handle_right_mtrl_alpha</item>
-    <item name="search_text_select_handle_middle" type="drawable">@*android:drawable/text_select_handle_middle_mtrl_alpha</item>
-</resources>
+</resources>
\ No newline at end of file
diff --git a/res/values/inspector_strings.xml b/res/values/inspector_strings.xml
index a70a274..a70a014 100644
--- a/res/values/inspector_strings.xml
+++ b/res/values/inspector_strings.xml
@@ -87,9 +87,9 @@
     <string name="metadata_address">Location</string>
 
     <!-- String label for developer/debug file details, specifying which stream types are available. -->
-    <string name="debug_stream_types">Stream types</string>
+    <string name="debug_stream_types" translatable="false">Stream types</string>
     <!-- String label for developer/debug file details, specifying the size of the file in bytes. -->
-    <string name="debug_raw_size">Raw size (bytes)</string>
+    <string name="debug_raw_size" translatable="false">Raw size (bytes)</string>
     <!-- String label for developer/debug file details, specifying a file's uri/content address. -->
     <string name="debug_content_uri" translatable="false">Uri</string>
     <!-- String label for developer/debug file details, specifying document id. -->
@@ -110,6 +110,8 @@
     <string name="debug_supports_delete" translatable="false">Supports delete</string>
     <!-- String label for developer/debug file details, specifying that a file has associated metadata. -->
     <string name="debug_supports_metadata" translatable="false">Supports metadata</string>
+    <!-- String label for developer/debug file details, specifying that a file can be moved. -->
+    <string name="debug_supports_move" translatable="false">Supports move</string>
     <!-- String label for developer/debug file details, specifying that a file can be removed. -->
     <string name="debug_supports_remove" translatable="false">Supports remove</string>
     <!-- String label for developer/debug file details, specifying that a file can be renamed. -->
diff --git a/res/values/mimes.xml b/res/values/mimes.xml
deleted file mode 100644
index 0559741..0000000
--- a/res/values/mimes.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2017 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Generic file type with an extention shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="generic_extention_file_type"><xliff:g id="extension" example="APE">%1$s</xliff:g> file</string>
-    <!-- Generic file type without an extention shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="generic_file_type">File</string>
-    <!-- Generic image file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="image_file_type">Image</string>
-    <!-- Image file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="image_extension_file_type"><xliff:g id="fileType" example="JPG">%1$s</xliff:g> image</string>
-    <!-- Generic audio file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="audio_file_type">Audio</string>
-    <!-- Audio file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="audio_extension_file_type"><xliff:g id="fileType" example="MP3">%1$s</xliff:g> audio</string>
-    <!-- Generic video file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="video_file_type">Video</string>
-    <!-- Video file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="video_extension_file_type"><xliff:g id="fileType" example="AVI">%1$s</xliff:g> video</string>
-    <!-- Archive file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="archive_file_type"><xliff:g id="fileType" example="Zip">%1$s</xliff:g> archive</string>
-    <!-- Android application file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="apk_file_type">Android application</string>
-    <!-- Plain text file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="txt_file_type">Plain text</string>
-    <!-- HTML file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="html_file_type">HTML document</string>
-    <!-- PDF file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="pdf_file_type">PDF document</string>
-    <!-- Word document file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="word_file_type">Word document</string>
-    <!-- PowerPoint presentation file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="ppt_file_type">PowerPoint presentation</string>
-    <!-- Excel spreadsheet file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="excel_file_type">Excel spreadsheet</string>
-    <!-- Google document file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gdoc_file_type">Google document</string>
-    <!-- Google spreadsheet file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gsheet_file_type">Google spreadsheet</string>
-    <!-- Google presentation file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gslides_file_type">Google presentation</string>
-    <!-- Google drawing file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gdraw_file_type">Google drawing</string>
-    <!-- Google table file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gtable_file_type">Google table</string>
-    <!-- Google form file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gform_file_type">Google form</string>
-    <!-- Google map file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gmap_file_type">Google map</string>
-    <!-- Google site file type shown in type column in list view. [CHAR LIMIT=30] -->
-    <string name="gsite_file_type">Google site</string>
-    <!-- Generic directory type shown when viewing a folder in the properties view -->
-    <string name="directory_type">Folder</string>
-</resources>
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
new file mode 100644
index 0000000..9a13207
--- /dev/null
+++ b/res/values/overlayable.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<!-- The collection of resources for theming the appearance of a device -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <overlayable name="DocumentsUICustomization">
+
+        <!-- START VENDOR CUSTOMIZATION -->
+        <policy type="product|system|vendor">
+            <!-- START THEME / STYLE -->
+            <item type="style" name="DocumentsTheme"/>
+            <!-- END THEME / STYLE -->
+
+            <!-- START COLOR -->
+            <item type="color" name="primary"/>
+            <!-- END COLOR -->
+
+            <!-- START DIMEN -->
+            <item type="dimen" name="grid_item_radius"/>
+            <item type="dimen" name="search_chip_radius"/>
+            <!-- END DIMEN -->
+
+            <!-- START DRAWABLE -->
+            <item type="drawable" name="ic_eject"/>
+            <item type="drawable" name="ic_root_download"/>
+            <item type="drawable" name="ic_sd_storage"/>
+            <item type="drawable" name="root_list_selector"/>
+            <!-- END DRAWABLE -->
+
+            <!-- START BOOLEAN CONFIG -->
+            <item type="bool" name="config_button_all_caps"/>
+            <item type="bool" name="config_default_show_device_root"/>
+            <item type="bool" name="feature_default_root_in_browse"/>
+            <item type="bool" name="handle_view_downloads_intent"/>
+            <item type="bool" name="is_launcher_enabled"/>
+            <item type="bool" name="show_search_bar"/>
+            <!-- END BOOLEAN CONFIG -->
+
+            <!-- START STRING CONFIG -->
+            <item type="string" name="config_fontFamily"/>
+            <item type="string" name="config_fontFamilyMedium"/>
+            <item type="string" name="default_root_uri"/>
+            <item type="string" name="preferred_root_package"/>
+            <item type="string" name="trusted_quick_viewer_package"/>
+            <!-- END STRING CONFIG -->
+
+        </policy>
+        <!-- END VENDOR CUSTOMIZATION -->
+
+    </overlayable>
+
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d671960..5559545 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -57,6 +57,10 @@
     <string name="menu_delete">Delete</string>
     <!-- Menu item title that selects all documents in the current directory [CHAR LIMIT=28] -->
     <string name="menu_select_all">Select all</string>
+    <!-- Menu item title that selects documents in the current directory [CHAR LIMIT=28] -->
+    <string name="menu_select">Select</string>
+    <!-- Menu item title that sort documents in the current directory [CHAR LIMIT=28] -->
+    <string name="menu_sort">Sort by...</string>
     <!-- Menu item title that copies the selected documents [CHAR LIMIT=28] -->
     <string name="menu_copy">Copy to\u2026</string>
     <!-- Menu item title that moves the selected documents [CHAR LIMIT=28] -->
@@ -121,6 +125,26 @@
     <string name="sort_dimension_size">Size</string>
     <!-- Table header for last modified time. [CHAR_LIMIT=18] -->
     <string name="sort_dimension_date">Modified</string>
+    <!-- Bottom sheet list title for file name ascending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_name_ascending">File name (A to Z)</string>
+    <!-- Bottom sheet list title for file type name ascending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_file_type_ascending">Type (A to Z)</string>
+    <!-- Bottom sheet list title for size ascending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_size_ascending">Size (smallest first)</string>
+    <!-- Bottom sheet list title for date ascending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_date_ascending">Modified (oldest first)</string>
+    <!-- Bottom sheet list title for file name descending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_name_descending">File name (Z to A)</string>
+    <!-- Bottom sheet list title for file type name descending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_file_type_descending">Type (Z to A)</string>
+    <!-- Bottom sheet list title for size descending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_size_descending">Size (largest first)</string>
+    <!-- Bottom sheet list title for date descending [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_date_descending">Modified (newest first)</string>
+    <!-- Bottom sheet dialog title [CHAR_LIMIT=42] -->
+    <string name="sort_dimension_dialog_title">Sort by</string>
+    <!-- Dropdown sort wiget button title. [CHAR_LIMIT=60] -->
+    <string name="sort_dimension_button_title">Sorted by <xliff:g id="label" example="File name (A to Z)">%s</xliff:g></string>
 
     <!--Table header for number of items in a folder.-->
     <string name="directory_items">Number of items</string>
@@ -130,6 +154,9 @@
     <!-- content description to describe descending sorting used with downward arrow in table header. -->
     <string name="sort_direction_descending">Descending</string>
 
+    <!-- content description to describe the action icon to open the app on the root item. -->
+    <string name="open_external_app">Open <xliff:g id="appName" example="Drive">%1$s</xliff:g></string>
+
     <!-- Accessibility title to open the drawer showing all roots where documents can be stored [CHAR LIMIT=32] -->
     <string name="drawer_open">Show roots</string>
     <!-- Accessibility title to close the drawer showing all roots where documents can be stored [CHAR LIMIT=32] -->
@@ -303,8 +330,6 @@
     <!-- Text in an alert dialog asking user to grant app access to all data in an external storage volume -->
     <string name="open_external_dialog_root_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
         access to your data, including photos and videos, on <xliff:g id="storage" example="SD Card"><i>^2</i></xliff:g>?</string>
-    <!-- Checkbox that allows user to not be questioned about the directory access request again -->
-    <string name="never_ask_again">Don\'t ask again</string>
     <!-- Text in the button asking user to allow access to a given directory. -->
     <string name="allow">Allow</string>
     <!-- Text in the button asking user to deny access to a given directory. -->
@@ -368,4 +393,68 @@
 
     <!-- Button for continuing a file operation in background, eg. copying, moving or extracting. [CHAR LIMIT=48] -->
     <string name="continue_in_background">Continue in background</string>
+
+    <!-- Label describing the number of selected items [CHAR LIMIT=48] -->
+    <plurals name="selected_count">
+        <item quantity="one"><xliff:g id="count" example="1">%1$d</xliff:g> selected</item>
+        <item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item>
+    </plurals>
+
+    <!-- Header title for list of documents in recent root. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_recent">Recent files on phone</string>
+    <!-- Header title for list of documents in global searching. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_global_search">Files on phone</string>
+    <!-- Header title for list of documents in media type root. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_media"><xliff:g id="label" example="images">%1$s</xliff:g> on phone</string>
+    <!-- Header title for list of documents in storage type root. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_storage">Files on <xliff:g id="device" example="Pixel">%1$s</xliff:g></string>
+    <!-- Header title for list of documents 3rd party provider root eg. Drive, Box. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_app">Files from <xliff:g id="label" example="Drive">%1$s</xliff:g></string>
+    <!-- Header title for list of documents 3rd party provider root eg. Drive, Box. with root summary. The summary is usually present by email account[CHAR_LIMIT=60] -->
+    <string name="root_info_header_app_with_summary">Files from <xliff:g id="label" example="Drive">%1$s</xliff:g> / <xliff:g id="summary" example="example@com">%2$s</xliff:g></string>
+    <!-- On photo picking state, the header title for list of documents in recent root. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_image_recent">Recent images on phone</string>
+    <!-- On photo picking state, the header title for list of documents in global searching. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_image_global_search">Images on phone</string>
+    <!-- On photo picking state, the header title for list of documents in storage type root. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_image_storage">Images on <xliff:g id="device" example="Pixel">%1$s</xliff:g></string>
+    <!-- On photo picking state, the header title for list of documents 3rd party provider root eg. Drive, Box. [CHAR_LIMIT=60] -->
+    <string name="root_info_header_image_app">Images from <xliff:g id="label" example="Drive">%1$s</xliff:g></string>
+    <!-- On photo picking state, the header title for list of documents 3rd party provider root eg. Drive, Box. with root summary. The summary is usually present by email account[CHAR_LIMIT=60] -->
+    <string name="root_info_header_image_app_with_summary">Images from <xliff:g id="label" example="Drive">%1$s</xliff:g> / <xliff:g id="summary" example="example@com">%2$s</xliff:g></string>
+
+    <!-- Title for images chip. [CHAR_LIMIT=25] -->
+    <string name="chip_title_images">Images</string>
+    <!-- Title for audio chip. [CHAR_LIMIT=25] -->
+    <string name="chip_title_audio">Audio</string>
+    <!-- Title for videos chip. [CHAR_LIMIT=25] -->
+    <string name="chip_title_videos">Videos</string>
+    <!-- Title for image chip. [CHAR_LIMIT=25] -->
+    <string name="chip_title_documents">Documents</string>
+
+    <!-- Hint on text input field for create new folder. [CHAR_LIMIT=48] -->
+    <string name="input_hint_new_folder">Folder name</string>
+    <!-- Hint on text input field for rename the file or the folder. [CHAR_LIMIT=48] -->
+    <string name="input_hint_rename">New name</string>
+
+    <!-- Content description for preivew function. -->
+    <string name="preview_file">Preview the file <xliff:g id="fileName" example="example.jpg">%1$s</xliff:g></string>
+
+    <!-- Apps row title. [CHAR_LIMIT=60] -->
+    <string name="apps_row_title">Browse files in other apps</string>
+
+    <!-- The default name to present the anonymous application-->
+    <string name="anonymous_application">Anonymous</string>
+    <!-- Button text show on open document tree flow. [CHAR_LIMIT=48] -->
+    <string name="open_tree_button">Allow access to \"<xliff:g id="directory" example="DCIM">%1$s</xliff:g>\"</string>
+    <!-- Confrim dialog title show on open document tree flow. [CHAR_LIMIT=60] -->
+    <string name="open_tree_dialog_title">Allow access to \"<xliff:g id="directory" example="DCIM">%1$s</xliff:g>\" in \"<xliff:g id="root" example="SD card">%2$s</xliff:g>\"?</string>
+    <!-- Confrim dialog message show on open document tree flow.-->
+    <string name="open_tree_dialog_message">It will allow \"<xliff:g id="appName" example="Drive">%1$s</xliff:g>\" to have full access to all files currently stored under this location, and any future content stored here.</string>
+
+    <!-- Search hint on search view. [CHAR LIMIT=48] -->
+    <string name="search_bar_hint">Search this phone</string>
+
+    <!-- Content description for deleting search history. [CHAR_LIMIT=60] -->
+    <string name="delete_search_history">Delete search history <xliff:g id="text" example="image">%1$s</xliff:g></string>
 </resources>
diff --git a/minimal/res/values/drawables.xml b/res/values/strings_font.xml
similarity index 64%
rename from minimal/res/values/drawables.xml
rename to res/values/strings_font.xml
index 2e5e77d..4279ef1 100644
--- a/minimal/res/values/drawables.xml
+++ b/res/values/strings_font.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -15,6 +15,10 @@
 -->
 
 <resources>
-    <item name="app_icon" type="drawable">@mipmap/ic_app_icon</item>
-    <item name="launcher_icon" type="drawable">@mipmap/ic_app_icon</item>
+
+    <!-- Name of a font family. If empty, falls back to platform default -->
+    <string name="config_fontFamily" translatable="false">sans-serif</string>
+    <!-- Name of the font family medium. -->
+    <string name="config_fontFamilyMedium" translatable="false">sans-serif-medium</string>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ec06169..10f9b05 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -15,37 +15,22 @@
 -->
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <style name="ActionBarTheme" parent="@*android:style/ThemeOverlay.Material.Dark.ActionBar">
-        <item name="android:colorControlNormal">@android:color/white</item>
-        <item name="android:textSelectHandle">@drawable/text_select_handle_middle</item>
-        <item name="android:textSelectHandleLeft">@drawable/text_select_handle_left</item>
-        <item name="android:textSelectHandleRight">@drawable/text_select_handle_right</item>
-        <item name="android:textCursorDrawable">@drawable/text_cursor</item>
-        <item name="android:textColorHighlight">@color/text_highlight</item>
-        <item name="android:textColorPrimary">@android:color/white</item>
+    <style name="ActionBarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
+        <item name="colorControlNormal">?android:textColorSecondary</item>
     </style>
-    <style name="ActionBarPopupTheme" parent="@*android:style/ThemeOverlay.Material.Light" />
 
-    <style name="DocumentsTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
-        <item name="actionBarWidgetTheme">@null</item>
-        <item name="actionBarTheme">@style/ActionBarTheme</item>
-        <item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
+    <style name="ActionModeStyle" parent="Widget.AppCompat.ActionMode">
+        <!-- attr "height" was used by support lib should not in overlay scope -->
+        <item name="height">@dimen/action_bar_space_height</item>
+        <item name="titleTextStyle">@style/ToolbarTitle</item>
+        <item name="android:layout_margin">@dimen/search_bar_margin</item>
+    </style>
 
-        <item name="android:windowBackground">@color/window_background</item>
-        <item name="android:colorPrimaryDark">@color/primary_dark</item>
-        <item name="android:colorPrimary">@color/primary</item>
-        <item name="android:colorAccent">@color/accent</item>
-        <item name="android:colorControlActivated">?android:attr/colorAccent</item>
-        <item name="android:queryBackground">@color/menu_search_background</item>
-
-        <item name="android:listDivider">@*android:drawable/list_divider_material</item>
-
-        <item name="android:windowActionBar">false</item>
-        <item name="android:windowActionModeOverlay">true</item>
-        <item name="android:windowNoTitle">true</item>
-
-        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+    <style name="CardViewStyle" parent="@style/Widget.MaterialComponents.CardView">
+        <item name="cardBackgroundColor">@color/app_background_color</item>
+        <item name="cardPreventCornerOverlap">false</item>
+        <item name="cardCornerRadius">@dimen/grid_item_radius</item>
+        <item name="cardElevation">@dimen/grid_item_elevation</item>
     </style>
 
     <style name="TrimmedHorizontalProgressBar" parent="android:Widget.Material.ProgressBar.Horizontal">
@@ -54,13 +39,62 @@
         <item name="android:maxHeight">3dp</item>
     </style>
 
-    <style name="BottomBarButton">
-        <item name="android:layout_height">36dp</item>
-        <item name="android:layout_gravity">center_vertical</item>
-        <item name="android:gravity">center</item>
-        <item name="android:fontFamily">sans-serif-medium</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:textAllCaps">true</item>
+    <style name="SnackbarButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
+        <item name="android:textColor">?android:colorPrimary</item>
     </style>
 
+    <style name="AutoCompleteTextViewStyle" parent="@style/Widget.AppCompat.AutoCompleteTextView">
+        <item name="android:textAppearance">@style/AutoCompleteText</item>
+    </style>
+
+    <style name="BottomSheetDialogStyle" parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog">
+        <item name="android:windowIsFloating">false</item>
+        <item name="bottomSheetStyle">@style/BottomSheet</item>
+        <item name="colorControlHighlight">@color/ripple_material_light</item>
+    </style>
+
+    <style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
+        <item name="android:background">@drawable/bottom_sheet_dialog_background</item>
+    </style>
+
+    <style name="OverflowButtonStyle" parent="@style/Widget.AppCompat.ActionButton.Overflow">
+        <item name="android:tint">?android:colorControlNormal</item>
+        <item name="android:minWidth">@dimen/button_touch_size</item>
+    </style>
+
+    <style name="OverflowMenuStyle" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
+        <item name="android:popupBackground">@drawable/menu_dropdown_panel</item>
+        <item name="android:dropDownWidth">wrap_content</item>
+        <item name="android:overlapAnchor">false</item>
+    </style>
+
+    <style name="MaterialAlertDialogTitleStyle" parent="@style/MaterialAlertDialog.MaterialComponents.Title.Text.CenterStacked">
+        <item name="android:textColor">?attr/colorOnSurface</item>
+        <item name="android:textSize">20sp</item>
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+    <style name="MaterialButton" parent="@style/Widget.MaterialComponents.Button.UnelevatedButton">
+        <item name="android:textAppearance">@style/MaterialButtonTextAppearance</item>
+    </style>
+
+    <style name="MaterialOutlinedButton" parent="@style/Widget.MaterialComponents.Button.OutlinedButton">
+        <item name="android:textAppearance">@style/MaterialButtonTextAppearance</item>
+    </style>
+
+    <style name="DialogTextButton" parent="@style/Widget.MaterialComponents.Button.TextButton.Dialog">
+        <item name="android:textAppearance">@style/MaterialButtonTextAppearance</item>
+    </style>
+
+    <style name="AlertDialogTheme" parent="@style/ThemeOverlay.AppCompat.Dialog.Alert">
+        <item name="buttonBarPositiveButtonStyle">@style/DialogTextButton</item>
+        <item name="buttonBarNegativeButtonStyle">@style/DialogTextButton</item>
+    </style>
+
+    <style name="MaterialAlertDialogTheme" parent="@style/ThemeOverlay.MaterialComponents.MaterialAlertDialog.Centered">
+        <item name="android:dialogCornerRadius">@dimen/grid_item_radius</item>
+        <item name="buttonBarPositiveButtonStyle">@style/DialogTextButton</item>
+        <item name="buttonBarNegativeButtonStyle">@style/DialogTextButton</item>
+        <item name="materialAlertDialogTitleTextStyle">@style/MaterialAlertDialogTitleStyle</item>
+    </style>
 </resources>
diff --git a/res/values/styles_text.xml b/res/values/styles_text.xml
new file mode 100644
index 0000000..5e3d57c
--- /dev/null
+++ b/res/values/styles_text.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <style name="SortTitle" parent="@style/TextAppearance.MaterialComponents.Headline6">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">11sp</item>
+    </style>
+
+    <style name="SortList" parent="@style/TextAppearance.AppCompat.Subhead">
+        <item name="android:textColor">@color/sort_list_text</item>
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+    <style name="SearchBarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Subtitle">
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:textSize">@dimen/search_bar_text_size</item>
+        <item name="fontFamily">@string/config_fontFamily</item>
+    </style>
+
+    <style name="SearchChipText">
+        <item name="android:textSize">14sp</item>
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+    <style name="AppsItemText">
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:textSize">12sp</item>
+        <item name="fontFamily">@string/config_fontFamily</item>
+    </style>
+
+    <style name="AutoCompleteText" parent="@style/TextAppearance.AppCompat.Medium">
+        <item name="fontFamily">@string/config_fontFamily</item>
+    </style>
+
+    <style name="CardPrimaryText" parent="@style/TextAppearance.AppCompat.Subhead">
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">14sp</item>
+    </style>
+
+    <style name="ToolbarTitle" parent="@android:style/TextAppearance.Material.Title">
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+    <style name="DrawerMenuTitle" parent="@android:style/TextAppearance.Material.Title">
+        <item name="android:textSize">24sp</item>
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+    <style name="DrawerMenuPrimary" parent="android:style/TextAppearance.Material.Body2">
+        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@color/item_root_primary_text</item>
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+    <style name="DrawerMenuSecondary" parent="android:style/TextAppearance.Material.Body2">
+        <item name="android:textSize">12sp</item>
+        <item name="android:textColor">@color/item_root_secondary_text</item>
+    </style>
+
+    <style name="InspectorKeySubTitle" parent="@style/TextAppearance.MaterialComponents.Subtitle1">
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+    </style>
+
+    <style name="MaterialButtonTextAppearance" parent="@style/TextAppearance.MaterialComponents.Button">
+        <item name="android:textAllCaps">@bool/config_button_all_caps</item>
+        <item name="fontFamily">@string/config_fontFamilyMedium</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/res/values/themes.xml b/res/values/themes.xml
new file mode 100644
index 0000000..971fa1f
--- /dev/null
+++ b/res/values/themes.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- DocumentsTheme is allow customize by run time overlay -->
+    <style name="DocumentsTheme" parent="@android:style/Theme.DeviceDefault.DocumentsUI">
+
+        <item name="android:actionBarSize">@dimen/action_bar_size</item>
+        <item name="android:actionModeBackground">?android:attr/colorBackground</item>
+
+        <!-- Color section -->
+        <item name="android:colorAccent">@color/primary</item>
+        <item name="android:colorBackground">@android:color/white</item>
+        <item name="android:colorBackgroundFloating">@color/background_floating</item>
+        <item name="android:colorControlHighlight">@color/ripple_material_light</item>
+        <item name="android:colorControlActivated">@color/primary</item>
+        <item name="android:colorPrimary">@color/primary</item>
+        <item name="android:colorSecondary">@color/secondary</item>
+        <item name="android:strokeColor">@color/hairline</item>
+
+        <!-- System | Widget section -->
+        <item name="android:listDivider">@drawable/list_divider</item>
+        <item name="android:statusBarColor">?android:colorBackground</item>
+        <item name="android:navigationBarColor">?android:colorBackground</item>
+        <item name="android:windowBackground">?android:colorBackground</item>
+        <item name="android:windowLightStatusBar">true</item>
+        <item name="android:windowLightNavigationBar">true</item>
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+
+        <!-- OEM should not overlay this attr -->
+        <item name="android:windowNoTitle">true</item>
+
+    </style>
+
+    <style name="DocumentsDefaultTheme" parent="@style/Theme.MaterialComponents.DayNight.NoActionBar">
+
+        <!-- This only used by support lib, not allow to overlay -->
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+
+        <!-- For material design widget, chips, buttons, not support attr-->
+        <item name="colorPrimary">@color/primary</item>
+        <item name="colorAccent">@color/primary</item>
+
+        <!-- TODO need to solve the error handle in GridItemThumbnail -->
+        <item name="gridItemTint">@color/item_doc_grid_tint</item>
+
+        <item name="actionBarTheme">@style/ActionBarTheme</item>
+        <item name="actionModeStyle">@style/ActionModeStyle</item>
+        <item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
+        <item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
+        <item name="alertDialogTheme">@style/AlertDialogTheme</item>
+        <item name="autoCompleteTextViewStyle">@style/AutoCompleteTextViewStyle</item>
+        <item name="bottomSheetDialogTheme">@style/BottomSheetDialogStyle</item>
+        <item name="materialButtonStyle">@style/MaterialButton</item>
+        <item name="materialButtonOutlinedStyle">@style/MaterialOutlinedButton</item>
+        <item name="materialCardViewStyle">@style/CardViewStyle</item>
+        <item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
+        <item name="queryBackground">@color/menu_search_background</item>
+        <item name="snackbarButtonStyle">@style/SnackbarButtonStyle</item>
+    </style>
+</resources>
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index 15425a8..423565d 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -20,13 +20,10 @@
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.app.Activity;
-import android.app.LoaderManager.LoaderCallbacks;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
-import android.content.Loader;
 import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.graphics.drawable.ColorDrawable;
@@ -34,11 +31,18 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
-import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.util.Pair;
 import android.view.DragEvent;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.FragmentActivity;
+import androidx.loader.app.LoaderManager.LoaderCallbacks;
+import androidx.loader.content.Loader;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.SelectionTracker;
+
 import com.android.documentsui.AbstractActionHandler.CommonAddons;
 import com.android.documentsui.LoadDocStackTask.LoadDocStackCallback;
 import com.android.documentsui.base.BooleanConsumer;
@@ -55,13 +59,11 @@
 import com.android.documentsui.files.LauncherActivity;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.GetRootDocumentTask;
+import com.android.documentsui.roots.LoadFirstRootTask;
 import com.android.documentsui.roots.LoadRootTask;
 import com.android.documentsui.roots.ProvidersAccess;
-import com.android.documentsui.selection.ContentLock;
-import com.android.documentsui.selection.MutableSelection;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.sidebar.EjectRootTask;
+import com.android.documentsui.sorting.SortListFragment;
 import com.android.documentsui.ui.Snackbars;
 
 import java.util.ArrayList;
@@ -75,7 +77,7 @@
 /**
  * Provides support for specializing the actions (openDocument etc.) to the host activity.
  */
-public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
+public abstract class AbstractActionHandler<T extends FragmentActivity & CommonAddons>
         implements ActionHandler {
 
     @VisibleForTesting
@@ -93,7 +95,7 @@
     protected final ProvidersAccess mProviders;
     protected final DocumentsAccess mDocs;
     protected final FocusHandler mFocusHandler;
-    protected final SelectionHelper mSelectionMgr;
+    protected final SelectionTracker<String> mSelectionMgr;
     protected final SearchViewManager mSearchMgr;
     protected final Lookup<String, Executor> mExecutors;
     protected final Injector<?> mInjector;
@@ -173,7 +175,7 @@
     }
 
     private void onAuthenticationResult(int resultCode) {
-        if (resultCode == Activity.RESULT_OK) {
+        if (resultCode == FragmentActivity.RESULT_OK) {
             Log.v(TAG, "Authentication was successful. Refreshing directory now.");
             mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
         }
@@ -211,7 +213,7 @@
 
     @Override
     public void openInNewWindow(DocumentStack path) {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_NEW_WINDOW);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_NEW_WINDOW);
 
         Intent intent = LauncherActivity.createLaunchIntent(mActivity);
         intent.putExtra(Shared.EXTRA_STACK, (Parcelable) path);
@@ -227,7 +229,7 @@
     }
 
     @Override
-    public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
+    public boolean openItem(ItemDetails<String> doc, @ViewType int type, @ViewType int fallback) {
         throw new UnsupportedOperationException("Can't open document.");
     }
 
@@ -273,7 +275,7 @@
 
     @Override
     public void selectAllFiles() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_SELECT_ALL);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_SELECT_ALL);
         Model model = mInjector.getModel();
 
         // Exclude disabled files
@@ -301,9 +303,14 @@
 
     @Override
     public void showCreateDirectoryDialog() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_CREATE_DIR);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_CREATE_DIR);
 
-        CreateDirectoryFragment.show(mActivity.getFragmentManager());
+        CreateDirectoryFragment.show(mActivity.getSupportFragmentManager());
+    }
+
+    @Override
+    public void showSortDialog() {
+        SortListFragment.show(mActivity.getSupportFragmentManager(), mState.sortModel);
     }
 
     @Override
@@ -342,6 +349,11 @@
         }
     }
 
+    @Override
+    public boolean previewItem(ItemDetails<String> doc) {
+        throw new UnsupportedOperationException("Can't handle preview.");
+    }
+
     private void openFolderInSearchResult(@Nullable DocumentStack stack, DocumentInfo doc) {
         if (stack == null) {
             mState.stack.popToRootDocument();
@@ -422,7 +434,7 @@
             mActivity.getActionBar().setBackgroundDrawable(new ColorDrawable(
                     mActivity.getResources().getColor(R.color.primary)));
             mActivity.getWindow().setStatusBarColor(
-                    mActivity.getResources().getColor(R.color.primary_dark));
+                    mActivity.getResources().getColor(android.R.color.background_dark));
         }
     }
 
@@ -475,6 +487,12 @@
     }
 
     @Override
+    public final void loadFirstRoot(Uri uri) {
+        new LoadFirstRootTask<>(mActivity, mProviders, mState, uri)
+                .executeOnExecutor(mExecutors.lookup(uri.getAuthority()));
+    }
+
+    @Override
     public void loadDocumentsForCurrentStack() {
         DocumentStack stack = mState.stack;
         if (!stack.isRecents() && stack.isEmpty()) {
@@ -487,7 +505,7 @@
             return;
         }
 
-        mActivity.getLoaderManager().restartLoader(LOADER_ID, null, mBindings);
+        mActivity.getSupportLoaderManager().restartLoader(LOADER_ID, null, mBindings);
     }
 
     protected final boolean launchToDocument(Uri uri) {
@@ -510,12 +528,12 @@
             mState.stack.reset(stack);
             mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
 
-            Metrics.logLaunchAtLocation(mActivity, mState, stack.getRoot().getUri());
+            Metrics.logLaunchAtLocation(mState, stack.getRoot().getUri());
         } else {
             Log.w(TAG, "Failed to launch into the given uri. Launch to default location.");
             launchToDefaultLocation();
 
-            Metrics.logLaunchAtLocation(mActivity, mState, null);
+            Metrics.logLaunchAtLocation(mState, null);
         }
     }
 
@@ -533,8 +551,13 @@
         loadRoot(Shared.getDefaultRootUri(mActivity));
     }
 
-    protected MutableSelection getStableSelection() {
-        MutableSelection selection = new MutableSelection();
+    protected final void loadRecent() {
+        mState.stack.changeRoot(mProviders.getRecentsRoot());
+        mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
+    }
+
+    protected MutableSelection<String> getStableSelection() {
+        MutableSelection<String> selection = new MutableSelection<>();
         mSelectionMgr.copySelection(selection);
         return selection;
     }
@@ -553,17 +576,29 @@
             Context context = mActivity;
 
             if (mState.stack.isRecents()) {
-
-                if (DEBUG) Log.d(TAG, "Creating new loader recents.");
-                return new RecentsLoader(
-                        context,
-                        mProviders,
-                        mState,
-                        mInjector.features,
-                        mExecutors,
-                        mInjector.fileTypeLookup);
+                if (mSearchMgr.isSearching()) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Creating new GlobalSearchLoader.");
+                    }
+                    return new GlobalSearchLoader(
+                            context,
+                            mProviders,
+                            mState,
+                            mExecutors,
+                            mInjector.fileTypeLookup,
+                            mSearchMgr.buildQueryArgs());
+                } else {
+                    if (DEBUG) {
+                        Log.d(TAG, "Creating new loader recents.");
+                    }
+                    return new RecentsLoader(
+                            context,
+                            mProviders,
+                            mState,
+                            mExecutors,
+                            mInjector.fileTypeLookup);
+                }
             } else {
-
                 Uri contentsUri = mSearchMgr.isSearching()
                         ? DocumentsContract.buildSearchDocumentsUri(
                             mState.stack.getRoot().authority,
@@ -573,31 +608,37 @@
                                 mState.stack.peek().authority,
                                 mState.stack.peek().documentId);
 
+                final Bundle queryArgs = mSearchMgr.isSearching()
+                        ? mSearchMgr.buildQueryArgs()
+                        : null;
+
                 if (mInjector.config.managedModeEnabled(mState.stack)) {
                     contentsUri = DocumentsContract.setManageMode(contentsUri);
                 }
 
-                if (DEBUG) Log.d(TAG,
+                if (DEBUG) {
+                    Log.d(TAG,
                         "Creating new directory loader for: "
-                                + DocumentInfo.debugString(mState.stack.peek()));
+                            + DocumentInfo.debugString(mState.stack.peek()));
+                }
 
                 return new DirectoryLoader(
                         mInjector.features,
                         context,
-                        mState.stack.getRoot(),
-                        mState.stack.peek(),
+                        mState,
                         contentsUri,
-                        mState.sortModel,
                         mInjector.fileTypeLookup,
                         mContentLock,
-                        mSearchMgr.isSearching());
+                        queryArgs);
             }
         }
 
         @Override
         public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
-            if (DEBUG) Log.d(TAG, "Loader has finished for: "
+            if (DEBUG) {
+                Log.d(TAG, "Loader has finished for: "
                     + DocumentInfo.debugString(mState.stack.peek()));
+            }
             assert(result != null);
 
             mInjector.getModel().update(result);
@@ -619,6 +660,10 @@
         void onDocumentPicked(DocumentInfo doc);
         RootInfo getCurrentRoot();
         DocumentInfo getCurrentDirectory();
+        /**
+         * Check whether current directory is root of recent.
+         */
+        boolean isInRecents();
         void setRootsDrawerOpen(boolean open);
 
         // TODO: Let navigator listens to State
diff --git a/src/com/android/documentsui/AbstractDragHost.java b/src/com/android/documentsui/AbstractDragHost.java
index a0d13a9..148e71c 100644
--- a/src/com/android/documentsui/AbstractDragHost.java
+++ b/src/com/android/documentsui/AbstractDragHost.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import android.annotation.CallSuper;
+import androidx.annotation.CallSuper;
 import android.view.View;
 
 import com.android.documentsui.services.FileOperationService;
diff --git a/src/com/android/documentsui/ActionHandler.java b/src/com/android/documentsui/ActionHandler.java
index ba20f34..5f74b58 100644
--- a/src/com/android/documentsui/ActionHandler.java
+++ b/src/com/android/documentsui/ActionHandler.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 import android.app.PendingIntent;
 import android.content.ContentProvider;
 import android.content.Intent;
@@ -24,12 +24,12 @@
 import android.net.Uri;
 import android.view.DragEvent;
 
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+
 import com.android.documentsui.base.BooleanConsumer;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.selection.ContentLock;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -37,6 +37,9 @@
 
 import javax.annotation.Nullable;
 
+/**
+ * Interface to handle action for document.
+ */
 public interface ActionHandler {
 
     @IntDef({
@@ -92,6 +95,8 @@
 
     void loadRoot(Uri uri);
 
+    void loadFirstRoot(Uri uri);
+
     void openSelectedInNewWindow();
 
     void openInNewWindow(DocumentStack path);
@@ -110,7 +115,7 @@
      * If container, then opens the container, otherwise views using the specified type of view.
      * If the primary view type is unavailable, then fallback to the alternative type of view.
      */
-    boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback);
+    boolean openItem(ItemDetails<String> doc, @ViewType int type, @ViewType int fallback);
 
     /**
      * This is called when user hovers over a doc for enough time during a drag n' drop, to open a
@@ -125,6 +130,8 @@
 
     void openContainerDocument(DocumentInfo doc);
 
+    boolean previewItem(ItemDetails<String> doc);
+
     void cutToClipboard();
 
     void copyToClipboard();
@@ -153,6 +160,8 @@
     void setDebugMode(boolean enabled);
     void showDebugMessage();
 
+    void showSortDialog();
+
     /**
      * Allow action handler to be initialized in a new scope.
      * @return this
diff --git a/src/com/android/documentsui/ActionModeController.java b/src/com/android/documentsui/ActionModeController.java
index dc453b7..7548250 100644
--- a/src/com/android/documentsui/ActionModeController.java
+++ b/src/com/android/documentsui/ActionModeController.java
@@ -18,8 +18,8 @@
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.annotation.IdRes;
-import android.annotation.Nullable;
+import androidx.annotation.IdRes;
+import androidx.annotation.Nullable;
 import android.app.Activity;
 import android.text.TextUtils;
 import android.util.Log;
@@ -33,33 +33,34 @@
 import com.android.documentsui.base.ConfirmationCallback.Result;
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.Menus;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
 import com.android.documentsui.ui.MessageBuilder;
 
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.SelectionTracker.SelectionObserver;
+
 /**
  * A controller that listens to selection changes and manages life cycles of action modes.
  */
-public class ActionModeController extends SelectionObserver
+public class ActionModeController extends SelectionObserver<String>
         implements ActionMode.Callback, ActionModeAddons {
 
     private static final String TAG = "ActionModeController";
 
     private final Activity mActivity;
-    private final SelectionHelper mSelectionMgr;
+    private final SelectionTracker<String> mSelectionMgr;
     private final MenuManager mMenuManager;
     private final MessageBuilder mMessages;
 
     private final ContentScope mScope = new ContentScope();
-    private final Selection mSelected = new Selection();
+    private final MutableSelection<String> mSelected = new MutableSelection<>();
 
     private @Nullable ActionMode mActionMode;
     private @Nullable Menu mMenu;
 
     public ActionModeController(
             Activity activity,
-            SelectionHelper selectionMgr,
+            SelectionTracker<String> selectionMgr,
             MenuManager menuManager,
             MessageBuilder messages) {
 
@@ -74,13 +75,17 @@
         mSelectionMgr.copySelection(mSelected);
         if (mSelected.size() > 0) {
             if (mActionMode == null) {
-                if (DEBUG) Log.d(TAG, "Starting action mode.");
+                if (DEBUG) {
+                    Log.d(TAG, "Starting action mode.");
+                }
                 mActionMode = mActivity.startActionMode(this);
             }
             updateActionMenu();
         } else {
             if (mActionMode != null) {
-                if (DEBUG) Log.d(TAG, "Finishing action mode.");
+                if (DEBUG) {
+                    Log.d(TAG, "Finishing action mode.");
+                }
                 mActionMode.finish();
             }
         }
@@ -103,12 +108,16 @@
     @Override
     public void onDestroyActionMode(ActionMode mode) {
         if (mActionMode == null) {
-            if (DEBUG) Log.w(TAG, "Received call to destroy action mode on alien mode object.");
+            if (DEBUG) {
+                Log.w(TAG, "Received call to destroy action mode on alien mode object.");
+            }
         }
 
         assert(mActionMode.equals(mode));
 
-        if (DEBUG) Log.d(TAG, "Handling action mode destroyed.");
+        if (DEBUG) {
+            Log.d(TAG, "Handling action mode destroyed.");
+        }
         mActionMode = null;
         mMenu = null;
 
@@ -126,7 +135,7 @@
     public boolean onCreateActionMode(ActionMode mode, Menu menu) {
         int size = mSelectionMgr.getSelection().size();
         mode.getMenuInflater().inflate(R.menu.action_mode_menu, menu);
-        mode.setTitle(TextUtils.formatSelectedCount(size));
+        mode.setTitle(mActivity.getResources().getQuantityString(R.plurals.selected_count, size));
 
         if (size > 0) {
 
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index bab713f..9954e9d 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -16,34 +16,43 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.Shared.EXTRA_BENCHMARK;
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.State.MODE_GRID;
 
-import android.app.Activity;
-import android.app.Fragment;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
+import android.graphics.Color;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.MessageQueue.IdleHandler;
 import android.preference.PreferenceManager;
 import android.provider.DocumentsContract;
-import android.support.annotation.CallSuper;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.Toolbar;
+import android.view.ViewGroup;
+import android.widget.Checkable;
+import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.ActionMenuView;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.Fragment;
 
 import com.android.documentsui.AbstractActionHandler.CommonAddons;
 import com.android.documentsui.Injector.Injected;
 import com.android.documentsui.NavigationViewManager.Breadcrumb;
+import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.RootInfo;
@@ -51,20 +60,24 @@
 import com.android.documentsui.base.State;
 import com.android.documentsui.base.State.ViewMode;
 import com.android.documentsui.dirlist.AnimationView;
+import com.android.documentsui.dirlist.AppsRowManager;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.prefs.LocalPreferences;
 import com.android.documentsui.prefs.Preferences;
 import com.android.documentsui.prefs.PreferencesMonitor;
 import com.android.documentsui.prefs.ScopedPreferences;
 import com.android.documentsui.queries.CommandInterceptor;
+import com.android.documentsui.queries.SearchChipData;
+import com.android.documentsui.queries.SearchFragment;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.queries.SearchViewManager.SearchManagerListener;
 import com.android.documentsui.roots.ProvidersCache;
-import com.android.documentsui.selection.Selection;
 import com.android.documentsui.sidebar.RootsFragment;
 import com.android.documentsui.sorting.SortController;
 import com.android.documentsui.sorting.SortModel;
 
+import com.google.android.material.appbar.AppBarLayout;
+
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -72,17 +85,17 @@
 import javax.annotation.Nullable;
 
 public abstract class BaseActivity
-        extends Activity implements CommonAddons, NavigationViewManager.Environment {
+        extends AppCompatActivity implements CommonAddons, NavigationViewManager.Environment {
 
     private static final String BENCHMARK_TESTING_PACKAGE = "com.android.documentsui.appperftests";
 
     protected SearchViewManager mSearchManager;
+    protected AppsRowManager mAppsRowManager;
     protected State mState;
 
     @Injected
     protected Injector<?> mInjector;
 
-    protected @Nullable RetainedState mRetainedState;
     protected ProvidersCache mProviders;
     protected DocumentsAccess mDocs;
     protected DrawerController mDrawer;
@@ -99,6 +112,7 @@
     private RootsMonitor<BaseActivity> mRootsMonitor;
 
     private long mStartTime;
+    private boolean mHasQueryContentFromIntent;
 
     private PreferencesMonitor mPreferencesMonitor;
 
@@ -120,6 +134,11 @@
         // Record the time when onCreate is invoked for metric.
         mStartTime = new Date().getTime();
 
+        // ToDo Create tool to check resource version before applyStyle for the theme
+        // If version code is not match, we should reset overlay package to default,
+        // in case Activity continueusly encounter resource not found exception
+        getTheme().applyStyle(R.style.DocumentsDefaultTheme, false);
+
         super.onCreate(icicle);
 
         final Intent intent = getIntent();
@@ -128,26 +147,24 @@
 
         setContentView(mLayoutId);
 
+        setContainer();
+
         mInjector = getInjector();
         mState = getState(icicle);
         mDrawer = DrawerController.create(this, mInjector.config);
-        Metrics.logActivityLaunch(this, mState, intent);
+        Metrics.logActivityLaunch(mState, intent);
 
-        // we're really interested in retainining state in our very complex
-        // DirectoryFragment. So we do a little code yoga to extend
-        // support to that fragment.
-        mRetainedState = (RetainedState) getLastNonConfigurationInstance();
         mProviders = DocumentsApplication.getProvidersCache(this);
         mDocs = DocumentsAccess.create(this);
 
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
-        setActionBar(toolbar);
+        setSupportActionBar(toolbar);
 
         Breadcrumb breadcrumb =
                 Shared.findView(this, R.id.dropdown_breadcrumb, R.id.horizontal_breadcrumb);
         assert(breadcrumb != null);
 
-        mNavigator = new NavigationViewManager(mDrawer, toolbar, mState, this, breadcrumb);
+        mNavigator = new NavigationViewManager(this, mDrawer, mState, this, breadcrumb);
         SearchManagerListener searchListener = new SearchManagerListener() {
             /**
              * Called when search results changed. Refreshes the content of the directory. It
@@ -156,11 +173,20 @@
              */
             @Override
             public void onSearchChanged(@Nullable String query) {
-                if (query != null) {
-                    Metrics.logUserAction(BaseActivity.this, Metrics.USER_ACTION_SEARCH);
+                if (mSearchManager.isSearching()) {
+                    Metrics.logSearchMode(query != null, mSearchManager.hasCheckedChip());
+                    if (mInjector.pickResult != null) {
+                        mInjector.pickResult.increaseActionCount();
+                    }
                 }
 
                 mInjector.actions.loadDocumentsForCurrentStack();
+
+                expandAppBar();
+                DirectoryFragment dir = getDirectoryFragment();
+                if (dir != null) {
+                    dir.scrollToTop();
+                }
             }
 
             @Override
@@ -173,6 +199,36 @@
             public void onSearchViewChanged(boolean opened) {
                 mNavigator.update();
             }
+
+            @Override
+            public void onSearchChipStateChanged(View v) {
+                final Checkable chip = (Checkable) v;
+                if (chip.isChecked()) {
+                    final SearchChipData item = (SearchChipData) v.getTag();
+                    Metrics.logUserAction(MetricConsts.USER_ACTION_SEARCH_CHIP);
+                    Metrics.logSearchType(item.getChipType());
+                }
+            }
+
+            @Override
+            public void onSearchViewFocusChanged(boolean hasFocus) {
+                final boolean isInitailSearch
+                        = !TextUtils.isEmpty(mSearchManager.getCurrentSearch())
+                        && TextUtils.isEmpty(mSearchManager.getSearchViewText());
+                if (hasFocus && (SearchFragment.get(getSupportFragmentManager()) == null)
+                        && !isInitailSearch) {
+                    SearchFragment.showFragment(getSupportFragmentManager(),
+                            mSearchManager.getSearchViewText());
+                }
+            }
+
+            @Override
+            public void onSearchViewClearClicked() {
+                if (SearchFragment.get(getSupportFragmentManager()) == null) {
+                    SearchFragment.showFragment(getSupportFragmentManager(),
+                            mSearchManager.getSearchViewText());
+                }
+            }
         };
 
         // "Commands" are meta input for controlling system behavior.
@@ -189,7 +245,26 @@
                         mInjector.features,
                         mInjector.debugHelper::toggleDebugMode,
                         cmdInterceptor);
-        mSearchManager = new SearchViewManager(searchListener, queryInterceptor, icicle);
+
+        ViewGroup chipGroup = findViewById(R.id.search_chip_group);
+        mSearchManager = new SearchViewManager(searchListener, queryInterceptor,
+                chipGroup, icicle);
+        // initialize the chip sets by accept mime types
+        mSearchManager.initChipSets(mState.acceptMimes);
+        // update the chip items by the mime types of the root
+        mSearchManager.updateChips(getCurrentRoot().derivedMimeTypes);
+        // parse the query content from intent when launch the
+        // activity at the first time
+        if (icicle == null) {
+            mHasQueryContentFromIntent = mSearchManager.parseQueryContentFromIntent(getIntent(),
+                    mState.action);
+        }
+
+        mNavigator.setSearchBarClickListener(v -> {
+            mSearchManager.onSearchBarClicked();
+            mNavigator.update();
+        });
+
         mSortController = SortController.create(this, mState.derivedMode, mState.sortModel);
 
         mPreferencesMonitor = new PreferencesMonitor(
@@ -199,7 +274,7 @@
         mPreferencesMonitor.start();
 
         // Base classes must update result in their onCreate.
-        setResult(Activity.RESULT_CANCELED);
+        setResult(AppCompatActivity.RESULT_CANCELED);
     }
 
     public void onPreferenceChanged(String pref) {
@@ -236,7 +311,15 @@
         getMenuInflater().inflate(R.menu.activity, menu);
         mNavigator.update();
         boolean fullBarSearch = getResources().getBoolean(R.bool.full_bar_search_view);
-        mSearchManager.install(menu, fullBarSearch);
+        boolean showSearchBar = getResources().getBoolean(R.bool.show_search_bar);
+        mSearchManager.install(menu, fullBarSearch, showSearchBar);
+
+        final ActionMenuView subMenuView = findViewById(R.id.sub_menu);
+        // If size is 0, it means the menu has not inflated and it should only do once.
+        if (subMenuView.getMenu().size() == 0) {
+            subMenuView.setOnMenuItemClickListener(this::onOptionsItemSelected);
+            getMenuInflater().inflate(R.menu.sub_menu, subMenuView.getMenu());
+        }
 
         return showMenu;
     }
@@ -246,6 +329,8 @@
     public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
         mSearchManager.showMenu(mState.stack);
+        final ActionMenuView subMenuView = findViewById(R.id.sub_menu);
+        mInjector.menuManager.updateSubMenu(subMenuView.getMenu());
         return true;
     }
 
@@ -260,7 +345,9 @@
     private State getState(@Nullable Bundle icicle) {
         if (icicle != null) {
             State state = icicle.<State>getParcelable(Shared.EXTRA_STATE);
-            if (DEBUG) Log.d(mTag, "Recovered existing state object: " + state);
+            if (DEBUG) {
+                Log.d(mTag, "Recovered existing state object: " + state);
+            }
             return state;
         }
 
@@ -280,11 +367,39 @@
         // Only show the toggle if advanced isn't forced enabled.
         state.showDeviceStorageOption = !Shared.mustShowDeviceRoot(intent);
 
-        if (DEBUG) Log.d(mTag, "Created new state object: " + state);
+        if (DEBUG) {
+            Log.d(mTag, "Created new state object: " + state);
+        }
 
         return state;
     }
 
+    private void setContainer() {
+        View root = findViewById(R.id.coordinator_layout);
+        root.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        root.setOnApplyWindowInsetsListener((v, insets) -> {
+            root.setPadding(insets.getSystemWindowInsetLeft(),
+                    insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), 0);
+
+            View saveContainer = findViewById(R.id.container_save);
+            saveContainer.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
+
+            View rootsContainer = findViewById(R.id.container_roots);
+            rootsContainer.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
+
+            return insets.consumeSystemWindowInsets();
+        });
+
+        getWindow().setNavigationBarDividerColor(Color.TRANSPARENT);
+        if (Build.VERSION.SDK_INT >= 29) {
+            getWindow().setNavigationBarColor(Color.TRANSPARENT);
+            getWindow().setNavigationBarContrastEnforced(true);
+        } else {
+            getWindow().setNavigationBarColor(getColor(R.color.nav_bar_translucent));
+        }
+    }
+
     @Override
     public void setRootsDrawerOpen(boolean open) {
         mNavigator.revealRootsDrawer(open);
@@ -323,6 +438,9 @@
                     TimeoutTask.DEFAULT_TIMEOUT,
                     doc -> mInjector.actions.openRootDocument(doc));
         }
+
+        expandAppBar();
+        updateHeaderTitle();
     }
 
     @Override
@@ -341,14 +459,6 @@
                 // SearchViewManager listens for this directly.
                 return false;
 
-            case R.id.option_menu_grid:
-                setViewMode(State.MODE_GRID);
-                return true;
-
-            case R.id.option_menu_list:
-                setViewMode(State.MODE_LIST);
-                return true;
-
             case R.id.option_menu_advanced:
                 onDisplayAdvancedDevices();
                 return true;
@@ -361,13 +471,25 @@
                 getInjector().actions.showDebugMessage();
                 return true;
 
+            case R.id.option_menu_sort:
+                getInjector().actions.showSortDialog();
+                return true;
+
+            case R.id.sub_menu_grid:
+                setViewMode(State.MODE_GRID);
+                return true;
+
+            case R.id.sub_menu_list:
+                setViewMode(State.MODE_LIST);
+                return true;
+
             default:
                 return super.onOptionsItemSelected(item);
         }
     }
 
     protected final @Nullable DirectoryFragment getDirectoryFragment() {
-        return DirectoryFragment.get(getFragmentManager());
+        return DirectoryFragment.get(getSupportFragmentManager());
     }
 
     /**
@@ -402,7 +524,7 @@
         // chance to spawn a fragment before we need to do it now. However if we spawned a fragment
         // already, system will automatically restore the fragment for us so we don't need to do
         // that manually this time.
-        if (DirectoryFragment.get(getFragmentManager()) == null) {
+        if (DirectoryFragment.get(getSupportFragmentManager()) == null) {
             refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
         }
     }
@@ -422,21 +544,30 @@
         // from the saved state passed in onCreate().
         mSearchManager.cancelSearch();
 
+        // only set the query content in the first launch
+        if (mHasQueryContentFromIntent) {
+            mHasQueryContentFromIntent = false;
+            mSearchManager.setCurrentSearch(mSearchManager.getQueryContentFromIntent());
+        }
+
         mState.derivedMode = LocalPreferences.getViewMode(this, mState.stack.getRoot(), MODE_GRID);
 
+        mNavigator.update();
+
         refreshDirectory(anim);
 
-        final RootsFragment roots = RootsFragment.get(getFragmentManager());
+        final RootsFragment roots = RootsFragment.get(getSupportFragmentManager());
         if (roots != null) {
             roots.onCurrentRootChanged();
         }
 
-        mNavigator.update();
-
         // Causes talkback to announce the activity's new title
         setTitle(mState.stack.getTitle());
 
         invalidateOptionsMenu();
+        mSortController.onViewModeChanged(mState.derivedMode);
+        mSearchManager.updateChips(getCurrentRoot().derivedMimeTypes);
+        mAppsRowManager.updateView(this);
     }
 
     private final List<String> getExcludedAuthorities() {
@@ -470,8 +601,8 @@
      */
     private void onDisplayAdvancedDevices() {
         boolean display = !mState.showAdvanced;
-        Metrics.logUserAction(this,
-                display ? Metrics.USER_ACTION_SHOW_ADVANCED : Metrics.USER_ACTION_HIDE_ADVANCED);
+        Metrics.logUserAction(display
+                ? MetricConsts.USER_ACTION_SHOW_ADVANCED : MetricConsts.USER_ACTION_HIDE_ADVANCED);
 
         mInjector.prefs.setShowDeviceRoot(display);
         updateDisplayAdvancedDevices(display);
@@ -479,7 +610,7 @@
 
     private void updateDisplayAdvancedDevices(boolean display) {
         mState.showAdvanced = display;
-        @Nullable RootsFragment fragment = RootsFragment.get(getFragmentManager());
+        @Nullable RootsFragment fragment = RootsFragment.get(getSupportFragmentManager());
         if (fragment != null) {
             // This also takes care of updating launcher shortcuts (which are roots :)
             fragment.onDisplayStateChanged();
@@ -492,18 +623,17 @@
      */
     void setViewMode(@ViewMode int mode) {
         if (mode == State.MODE_GRID) {
-            Metrics.logUserAction(this, Metrics.USER_ACTION_GRID);
+            Metrics.logUserAction(MetricConsts.USER_ACTION_GRID);
         } else if (mode == State.MODE_LIST) {
-            Metrics.logUserAction(this, Metrics.USER_ACTION_LIST);
+            Metrics.logUserAction(MetricConsts.USER_ACTION_LIST);
         }
 
         LocalPreferences.setViewMode(this, getCurrentRoot(), mode);
         mState.derivedMode = mode;
 
-        // view icon needs to be updated, but we *could* do it
-        // in onOptionsItemSelected, and not do the full invalidation
-        // But! That's a larger refactoring we'll save for another day.
-        invalidateOptionsMenu();
+        final ActionMenuView subMenuView = findViewById(R.id.sub_menu);
+        mInjector.menuManager.updateSubMenu(subMenuView.getMenu());
+
         DirectoryFragment dir = getDirectoryFragment();
         if (dir != null) {
             dir.onViewModeChanged();
@@ -516,6 +646,101 @@
         // TODO: Isolate this behavior to PickActivity.
     }
 
+    public void expandAppBar() {
+        final AppBarLayout appBarLayout = findViewById(R.id.app_bar);
+        if (appBarLayout != null) {
+            appBarLayout.setExpanded(true);
+        }
+    }
+
+    public void updateHeaderTitle() {
+        if (!mState.stack.isInitialized()) {
+            //stack has not initialized, the header will update after the stack finishes loading
+            return;
+        }
+
+        final RootInfo root = mState.stack.getRoot();
+        final String rootTitle = root.title;
+        String result;
+
+        switch (root.derivedType) {
+            case RootInfo.TYPE_RECENTS:
+                result = getHeaderRecentTitle();
+                break;
+            case RootInfo.TYPE_IMAGES:
+            case RootInfo.TYPE_VIDEO:
+            case RootInfo.TYPE_AUDIO:
+                result = getString(R.string.root_info_header_media, rootTitle);
+                break;
+            case RootInfo.TYPE_DOWNLOADS:
+            case RootInfo.TYPE_LOCAL:
+            case RootInfo.TYPE_MTP:
+            case RootInfo.TYPE_SD:
+            case RootInfo.TYPE_USB:
+                result = getHeaderStorageTitle(rootTitle);
+                break;
+            default:
+                final String summary = root.summary;
+                result = getHeaderDefaultTitle(rootTitle, summary);
+                break;
+        }
+
+        TextView headerTitle = findViewById(R.id.header_title);
+        headerTitle.setText(result);
+    }
+
+    private String getHeaderRecentTitle() {
+        // If stack size larger than 1, it means user global search than enter a folder, but search
+        // is not expanded on that time.
+        boolean isGlobalSearch = mSearchManager.isSearching() || mState.stack.size() > 1;
+        if (mState.isPhotoPicking()) {
+            final int resId = isGlobalSearch
+                    ? R.string.root_info_header_image_global_search
+                    : R.string.root_info_header_image_recent;
+            return getString(resId);
+        } else {
+            final int resId = isGlobalSearch
+                    ? R.string.root_info_header_global_search
+                    : R.string.root_info_header_recent;
+            return getString(resId);
+        }
+    }
+
+    private String getHeaderStorageTitle(String rootTitle) {
+        final int resId = mState.isPhotoPicking()
+                ? R.string.root_info_header_image_storage : R.string.root_info_header_storage;
+        return getString(resId, rootTitle);
+    }
+
+    private String getHeaderDefaultTitle(String rootTitle, String summary) {
+        if (TextUtils.isEmpty(summary)) {
+            final int resId = mState.isPhotoPicking()
+                    ? R.string.root_info_header_image_app : R.string.root_info_header_app;
+            return getString(resId, rootTitle);
+        } else {
+            final int resId = mState.isPhotoPicking()
+                    ? R.string.root_info_header_image_app_with_summary
+                    : R.string.root_info_header_app_with_summary;
+            return getString(resId, rootTitle, summary);
+        }
+    }
+
+    /**
+     * Get title string equal to the string action bar displayed.
+     * @return current directory title name
+     */
+    public String getCurrentTitle() {
+        if (!mState.stack.isInitialized()) {
+            return null;
+        }
+
+        if (mState.stack.size() > 1) {
+            return getCurrentDirectory().displayName;
+        } else {
+            return getCurrentRoot().title;
+        }
+    }
+
     @Override
     protected void onSaveInstanceState(Bundle state) {
         super.onSaveInstanceState(state);
@@ -524,29 +749,6 @@
     }
 
     @Override
-    protected void onRestoreInstanceState(Bundle state) {
-        super.onRestoreInstanceState(state);
-    }
-
-    /**
-     * Delegate ths call to the current fragment so it can save selection.
-     * Feel free to expand on this with other useful state.
-     */
-    @Override
-    public RetainedState onRetainNonConfigurationInstance() {
-        RetainedState retained = new RetainedState();
-        DirectoryFragment fragment = DirectoryFragment.get(getFragmentManager());
-        if (fragment != null) {
-            fragment.retainState(retained);
-        }
-        return retained;
-    }
-
-    public @Nullable RetainedState getRetainedState() {
-        return mRetainedState;
-    }
-
-    @Override
     public boolean isSearchExpanded() {
         return mSearchManager.isExpanded();
     }
@@ -566,6 +768,11 @@
         return mState.stack.peek();
     }
 
+    @Override
+    public boolean isInRecents() {
+        return mState.stack.isRecents();
+    }
+
     @VisibleForTesting
     public void addEventListener(EventListener listener) {
         mEventListeners.add(listener);
@@ -604,6 +811,7 @@
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
         mInjector.actions.onActivityResult(requestCode, resultCode, data);
     }
 
@@ -615,6 +823,11 @@
      */
     protected boolean popDir() {
         if (mState.stack.size() > 1) {
+            final DirectoryFragment fragment = getDirectoryFragment();
+            if (fragment != null) {
+                fragment.stopScroll();
+            }
+
             mState.stack.pop();
             refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE);
             return true;
@@ -623,7 +836,7 @@
     }
 
     protected boolean focusSidebar() {
-        RootsFragment rf = RootsFragment.get(getFragmentManager());
+        RootsFragment rf = RootsFragment.get(getSupportFragmentManager());
         assert (rf != null);
         return rf.requestFocus();
     }
@@ -651,8 +864,7 @@
                             finish();
                         }
 
-                        Metrics.logStartupMs(
-                                BaseActivity.this, (int) (new Date().getTime() - mStartTime));
+                        Metrics.logStartupMs((int) (new Date().getTime() - mStartTime));
 
                         // Remove the idle handler.
                         return false;
@@ -662,14 +874,6 @@
         });
     }
 
-    public static final class RetainedState {
-        public @Nullable Selection selection;
-
-        public boolean hasSelection() {
-            return selection != null;
-        }
-    }
-
     @VisibleForTesting
     protected interface EventListener {
         /**
diff --git a/src/com/android/documentsui/ContentLock.java b/src/com/android/documentsui/ContentLock.java
new file mode 100644
index 0000000..239bf7a
--- /dev/null
+++ b/src/com/android/documentsui/ContentLock.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 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.documentsui;
+
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
+
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.OperationMonitor;
+
+/**
+ * ContentLock provides a mechanism to block content from reloading while selection
+ * activities like gesture and band selection are active. Clients using live data
+ * (data loaded, for example by a {@link Loader}), should route calls to load
+ * content through this lock using {@link ContentLock#runWhenUnlocked(Runnable)}.
+ */
+public final class ContentLock {
+
+    private static final String TAG = "ContentLock";
+
+    private final OperationMonitor mMonitor = new OperationMonitor();
+
+    @GuardedBy("this")
+    private @Nullable Runnable mCallback;
+
+    public ContentLock() {
+        mMonitor.addListener(() -> {
+            if (DEBUG) {
+                Log.d(TAG, "monitor listener, is locked : " + isLocked());
+            }
+            if (!isLocked()) {
+                synchronized (this) {
+                    final Runnable callback = mCallback;
+                    if (callback != null) {
+                        callback.run();
+                        mCallback = null;
+                    }
+                }
+            }
+        });
+    }
+
+    public OperationMonitor getMonitor() {
+        return mMonitor;
+    }
+
+    /**
+     * Returns true if locked.
+     */
+    private boolean isLocked() {
+        return mMonitor.isStarted();
+    }
+
+    /**
+     * Attempts to run the given Runnable if not-locked, or else the Runnable is set to be ran next
+     * (replacing any previous set Runnables).
+     */
+    public synchronized void runWhenUnlocked(Runnable runnable) {
+        if (DEBUG) {
+            Log.d(TAG, "run when unlock, is locked : " + isLocked());
+        }
+        if (!isLocked()) {
+            runnable.run();
+        } else {
+            mCallback = runnable;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/CreateDirectoryFragment.java b/src/com/android/documentsui/CreateDirectoryFragment.java
index ab31544..756b555 100644
--- a/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -16,12 +16,11 @@
 
 package com.android.documentsui;
 
+import static android.content.ContentResolver.wrap;
+
 import static com.android.documentsui.base.SharedMinimal.TAG;
 
-import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -30,23 +29,31 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.FileUtils;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
-import android.support.design.widget.Snackbar;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.view.inputmethod.EditorInfo;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.inputmethod.EditorInfo;
 import android.widget.EditText;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.ui.Snackbars;
 
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputLayout;
+
 /**
  * Dialog to create a new directory.
  */
@@ -63,12 +70,15 @@
         final Context context = getActivity();
         final ContentResolver resolver = context.getContentResolver();
 
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
         final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
 
         final View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false);
         final EditText editText = (EditText) view.findViewById(android.R.id.text1);
 
+        final TextInputLayout inputWrapper = view.findViewById(R.id.input_wrapper);
+        inputWrapper.setHint(getString(R.string.input_hint_new_folder));
+
         builder.setTitle(R.string.menu_create_dir);
         builder.setView(view);
 
@@ -102,7 +112,7 @@
                         return false;
                     }
                 });
-
+        editText.requestFocus();
 
         return dialog;
     }
@@ -140,14 +150,14 @@
                 client = DocumentsApplication.acquireUnstableProviderOrThrow(
                         resolver, mCwd.derivedUri.getAuthority());
                 final Uri childUri = DocumentsContract.createDocument(
-                        client, mCwd.derivedUri, Document.MIME_TYPE_DIR, mDisplayName);
+                        wrap(client), mCwd.derivedUri, Document.MIME_TYPE_DIR, mDisplayName);
                 DocumentInfo doc = DocumentInfo.fromUri(resolver, childUri);
                 return doc.isDirectory() ? doc : null;
             } catch (Exception e) {
                 Log.w(TAG, "Failed to create directory", e);
                 return null;
             } finally {
-                ContentProviderClient.releaseQuietly(client);
+                FileUtils.closeQuietly(client);
             }
         }
 
@@ -156,11 +166,11 @@
             if (result != null) {
                 // Navigate into newly created child
                 mActivity.onDirectoryCreated(result);
-                Metrics.logCreateDirOperation(getContext());
+                Metrics.logCreateDirOperation();
             } else {
                 Snackbars.makeSnackbar(mActivity, R.string.create_error, Snackbar.LENGTH_SHORT)
                         .show();
-                Metrics.logCreateDirError(getContext());
+                Metrics.logCreateDirError();
             }
             mActivity.setPending(false);
         }
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 55900e6..d65b4c3 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -16,18 +16,18 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
-import android.content.AsyncTaskLoader;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.FileUtils;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.OperationCanceledException;
@@ -35,24 +35,29 @@
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
+import androidx.loader.content.AsyncTaskLoader;
+
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.base.DebugFlags;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.FilteringCursorWrapper;
 import com.android.documentsui.base.Lookup;
+import com.android.documentsui.base.MimeTypes;
 import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.State;
 import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.documentsui.selection.ContentLock;
 import com.android.documentsui.sorting.SortModel;
 
-import libcore.io.IoUtils;
+import java.util.concurrent.Executor;
 
 public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
 
     private static final String TAG = "DirectoryLoader";
 
     private static final String[] SEARCH_REJECT_MIMES = new String[] { Document.MIME_TYPE_DIR };
+    private static final String[] PHOTO_PICKING_ACCEPT_MIMES = new String[]
+            {Document.MIME_TYPE_DIR, MimeTypes.IMAGE_MIME};
 
     private final LockingContentObserver mObserver;
     private final RootInfo mRoot;
@@ -60,6 +65,8 @@
     private final SortModel mModel;
     private final Lookup<String, String> mFileTypeLookup;
     private final boolean mSearchMode;
+    private final Bundle mQueryArgs;
+    private final boolean mPhotoPicking;
 
     private DocumentInfo mDoc;
     private CancellationSignal mSignal;
@@ -70,23 +77,28 @@
     public DirectoryLoader(
             Features features,
             Context context,
-            RootInfo root,
-            DocumentInfo doc,
+            State state,
             Uri uri,
-            SortModel model,
             Lookup<String, String> fileTypeLookup,
             ContentLock lock,
-            boolean inSearchMode) {
+            Bundle queryArgs) {
 
-        super(context, ProviderExecutor.forAuthority(root.authority));
+        super(context);
         mFeatures = features;
-        mRoot = root;
+        mRoot = state.stack.getRoot();
         mUri = uri;
-        mModel = model;
-        mDoc = doc;
+        mModel = state.sortModel;
+        mDoc = state.stack.peek();
         mFileTypeLookup = fileTypeLookup;
-        mSearchMode = inSearchMode;
+        mSearchMode = queryArgs != null;
+        mQueryArgs = queryArgs;
         mObserver = new LockingContentObserver(lock, this::onContentChanged);
+        mPhotoPicking = state.isPhotoPicking();
+    }
+
+    @Override
+    protected Executor getExecutor() {
+        return ProviderExecutor.forAuthority(mRoot.authority);
     }
 
     @Override
@@ -113,21 +125,21 @@
             }
             result.client = client;
 
-            Resources resources = getContext().getResources();
-            if (mFeatures.isContentPagingEnabled()) {
-                Bundle queryArgs = new Bundle();
-                mModel.addQuerySortArgs(queryArgs);
+            final Bundle queryArgs = new Bundle();
+            mModel.addQuerySortArgs(queryArgs);
 
+            if (mSearchMode) {
+                queryArgs.putAll(mQueryArgs);
+            }
+
+            if (mFeatures.isContentPagingEnabled()) {
                 // TODO: At some point we don't want forced flags to override real paging...
                 // and that point is when we have real paging.
                 DebugFlags.addForcedPagingArgs(queryArgs);
-
-                cursor = client.query(mUri, null, queryArgs, mSignal);
-            } else {
-                cursor = client.query(
-                        mUri, null, null, null, mModel.getDocumentSortQuery(), mSignal);
             }
 
+            cursor = client.query(mUri, null, queryArgs, mSignal);
+
             if (cursor == null) {
                 throw new RemoteException("Provider returned null");
             }
@@ -141,10 +153,14 @@
                 cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES);
             }
 
+            if (mPhotoPicking) {
+                cursor = new FilteringCursorWrapper(cursor, PHOTO_PICKING_ACCEPT_MIMES, null);
+            }
+
             // TODO: When API tweaks have landed, use ContentResolver.EXTRA_HONORED_ARGS
             // instead of checking directly for ContentResolver.QUERY_ARG_SORT_COLUMNS (won't work)
             if (mFeatures.isContentPagingEnabled()
-                        && cursor.getExtras().containsKey(ContentResolver.QUERY_ARG_SORT_COLUMNS)) {
+                    && cursor.getExtras().containsKey(ContentResolver.QUERY_ARG_SORT_COLUMNS)) {
                 if (VERBOSE) Log.d(TAG, "Skipping sort of pre-sorted cursor. Booya!");
             } else {
                 cursor = mModel.sortCursor(cursor, mFileTypeLookup);
@@ -158,7 +174,7 @@
                 mSignal = null;
             }
             // TODO: Remove this call.
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(client);
         }
 
         return result;
@@ -178,7 +194,7 @@
     @Override
     public void deliverResult(DirectoryResult result) {
         if (isReset()) {
-            IoUtils.closeQuietly(result);
+            FileUtils.closeQuietly(result);
             return;
         }
         DirectoryResult oldResult = mResult;
@@ -189,7 +205,7 @@
         }
 
         if (oldResult != null && oldResult != result) {
-            IoUtils.closeQuietly(oldResult);
+            FileUtils.closeQuietly(oldResult);
         }
     }
 
@@ -210,7 +226,7 @@
 
     @Override
     public void onCanceled(DirectoryResult result) {
-        IoUtils.closeQuietly(result);
+        FileUtils.closeQuietly(result);
     }
 
     @Override
@@ -220,7 +236,7 @@
         // Ensure the loader is stopped
         onStopLoading();
 
-        IoUtils.closeQuietly(mResult);
+        FileUtils.closeQuietly(mResult);
         mResult = null;
 
         getContext().getContentResolver().unregisterContentObserver(mObserver);
@@ -243,6 +259,9 @@
 
         @Override
         public void onChange(boolean selfChange) {
+            if (DEBUG) {
+                Log.d(TAG, "Directory content updated.");
+            }
             mLock.runWhenUnlocked(mContentChangedCallback);
         }
     }
diff --git a/src/com/android/documentsui/DirectoryResult.java b/src/com/android/documentsui/DirectoryResult.java
index 58746e5..a4068de 100644
--- a/src/com/android/documentsui/DirectoryResult.java
+++ b/src/com/android/documentsui/DirectoryResult.java
@@ -23,7 +23,7 @@
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.base.DocumentInfo;
 
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 
 public class DirectoryResult implements AutoCloseable {
 
@@ -34,7 +34,7 @@
 
     @Override
     public void close() {
-        IoUtils.closeQuietly(cursor);
+        FileUtils.closeQuietly(cursor);
         if (client != null && doc.isInArchive()) {
             ArchivesProvider.releaseArchive(client, doc.derivedUri);
         }
diff --git a/src/com/android/documentsui/DocsSelectionHelper.java b/src/com/android/documentsui/DocsSelectionHelper.java
index ebdfc9b..b7a720c 100644
--- a/src/com/android/documentsui/DocsSelectionHelper.java
+++ b/src/com/android/documentsui/DocsSelectionHelper.java
@@ -16,50 +16,42 @@
 
 package com.android.documentsui;
 
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
+import android.os.Bundle;
+import android.view.MotionEvent;
 
-import com.android.documentsui.selection.DefaultSelectionHelper;
-import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode;
-import com.android.documentsui.selection.MutableSelection;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
+import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.selection.ItemDetailsLookup;
+import androidx.recyclerview.selection.ItemKeyProvider;
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.Selection;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
 
 import java.util.Set;
 
-import javax.annotation.Nullable;
-
 /**
  * DocumentsUI SelectManager implementation that creates delegate instances
  * each time reset is called.
  */
-public final class DocsSelectionHelper extends SelectionHelper {
+public final class DocsSelectionHelper extends SelectionTracker<String> {
 
     private final DelegateFactory mFactory;
-    private final @SelectionMode int mSelectionMode;
 
     // initialize to a dummy object incase we get some input
     // event drive calls before we're properly initialized.
     // See: b/69306667.
-    private SelectionHelper mDelegate = new DummySelectionHelper();
+    private SelectionTracker<String> mDelegate = new DummySelectionTracker<>();
 
     @VisibleForTesting
-    DocsSelectionHelper(DelegateFactory factory, @SelectionMode int mode) {
+    DocsSelectionHelper(DelegateFactory factory) {
         mFactory = factory;
-        mSelectionMode = mode;
     }
 
-    public SelectionHelper reset(
-            RecyclerView.Adapter<?> adapter,
-            StableIdProvider stableIds,
-            SelectionPredicate canSetState) {
-
+    public void reset(SelectionTracker<String> selectionTracker) {
         if (mDelegate != null) {
             mDelegate.clearSelection();
         }
-
-        mDelegate = mFactory.create(mSelectionMode, adapter, stableIds, canSetState);
-        return this;
+        mDelegate = mFactory.create(selectionTracker);
     }
 
     @Override
@@ -73,12 +65,12 @@
     }
 
     @Override
-    public Selection getSelection() {
+    public Selection<String> getSelection() {
         return mDelegate.getSelection();
     }
 
     @Override
-    public void copySelection(Selection dest) {
+    public void copySelection(MutableSelection<String> dest) {
         mDelegate.copySelection(dest);
     }
 
@@ -94,18 +86,13 @@
     }
 
     @Override
-    public void restoreSelection(Selection other) {
-        mDelegate.restoreSelection(other);
-    }
-
-    @Override
     public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
         return mDelegate.setItemsSelected(ids, selected);
     }
 
     @Override
-    public void clearSelection() {
-        mDelegate.clearSelection();
+    public boolean clearSelection() {
+        return mDelegate.clearSelection();
     }
 
     @Override
@@ -129,26 +116,6 @@
     }
 
     @Override
-    public void extendProvisionalRange(int pos) {
-        mDelegate.extendProvisionalRange(pos);
-    }
-
-    @Override
-    public void clearProvisionalSelection() {
-        mDelegate.clearProvisionalSelection();
-    }
-
-    @Override
-    public void setProvisionalSelection(Set<String> newSelection) {
-        mDelegate.setProvisionalSelection(newSelection);
-    }
-
-    @Override
-    public void mergeProvisionalSelection() {
-        mDelegate.mergeProvisionalSelection();
-    }
-
-    @Override
     public void endRange() {
         mDelegate.endRange();
     }
@@ -163,16 +130,45 @@
         mDelegate.anchorRange(position);
     }
 
-    public static DocsSelectionHelper createMultiSelect() {
-        return new DocsSelectionHelper(
-                DelegateFactory.INSTANCE,
-                DefaultSelectionHelper.MODE_MULTIPLE);
+    @Override
+    public void onSaveInstanceState(Bundle state) {
+        mDelegate.onSaveInstanceState(state);
     }
 
-    public static DocsSelectionHelper createSingleSelect() {
-        return new DocsSelectionHelper(
-                DelegateFactory.INSTANCE,
-                DefaultSelectionHelper.MODE_SINGLE);
+    @Override
+    public void onRestoreInstanceState(Bundle state) {
+        mDelegate.onRestoreInstanceState(state);
+    }
+
+    // Below overridden protected methods are not used for delegation. These empty implementations
+    // are just required by abstract declaration of parent class.
+    @Override
+    protected void restoreSelection(Selection<String> selection) {
+    }
+
+    @Override
+    protected AdapterDataObserver getAdapterDataObserver() {
+        return null;
+    }
+
+    @Override
+    protected void extendProvisionalRange(int position) {
+    }
+
+    @Override
+    protected void setProvisionalSelection(Set<String> newSelection) {
+    }
+
+    @Override
+    protected void clearProvisionalSelection() {
+    }
+
+    @Override
+    protected void mergeProvisionalSelection() {
+    }
+
+    public static DocsSelectionHelper create() {
+        return new DocsSelectionHelper(DelegateFactory.INSTANCE);
     }
 
     /**
@@ -183,107 +179,30 @@
     static class DelegateFactory {
         static final DelegateFactory INSTANCE = new DelegateFactory();
 
-        SelectionHelper create(
-                @SelectionMode int mode,
-                RecyclerView.Adapter<?> adapter,
-                StableIdProvider stableIds,
-                SelectionPredicate canSetState) {
-
-            return new DefaultSelectionHelper(mode, adapter, stableIds, canSetState);
+        SelectionTracker<String> create(SelectionTracker<String> selectionTracker) {
+            return selectionTracker;
         }
     }
 
     /**
-     * A dummy SelectHelper used by DocsSelectionHelper before a real
-     * SelectionHelper has been initialized by DirectoryFragment.
+     * Facilitates the use of ItemDetailsLookup.
      */
-    private static final class DummySelectionHelper extends SelectionHelper {
+    public static abstract class DocDetailsLookup extends ItemDetailsLookup<String> {
 
+        // Override as public for usages in other packages.
         @Override
-        public void addObserver(SelectionObserver listener) {
+        public boolean overItemWithSelectionKey(MotionEvent e) {
+            return super.overItemWithSelectionKey(e);
         }
+    }
 
-        @Override
-        public boolean hasSelection() {
-            return false;
-        }
+    /**
+     * Facilitates the use of stable ids.
+     */
+    public static abstract class StableIdProvider extends ItemKeyProvider<String> {
 
-        @Override
-        public Selection getSelection() {
-            return new MutableSelection();
-        }
-
-        @Override
-        public void copySelection(Selection dest) {
-        }
-
-        @Override
-        public boolean isSelected(String id) {
-            return false;
-        }
-
-        @VisibleForTesting
-        public void replaceSelection(Iterable<String> ids) {
-        }
-
-        @Override
-        public void restoreSelection(Selection other) {
-        }
-
-        @Override
-        public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
-            return false;
-        }
-
-        @Override
-        public void clearSelection() {
-        }
-
-        @Override
-        public boolean select(String modelId) {
-            return false;
-        }
-
-        @Override
-        public boolean deselect(String modelId) {
-            return false;
-        }
-
-        @Override
-        public void startRange(int pos) {
-        }
-
-        @Override
-        public void extendRange(int pos) {
-        }
-
-        @Override
-        public void extendProvisionalRange(int pos) {
-        }
-
-        @Override
-        public void clearProvisionalSelection() {
-        }
-
-        @Override
-        public void setProvisionalSelection(Set<String> newSelection) {
-        }
-
-        @Override
-        public void mergeProvisionalSelection() {
-        }
-
-        @Override
-        public void endRange() {
-        }
-
-        @Override
-        public boolean isRangeActive() {
-            return false;
-        }
-
-        @Override
-        public void anchorRange(int position) {
+        protected StableIdProvider() {
+            super(ItemKeyProvider.SCOPE_MAPPED);
         }
     }
 }
diff --git a/src/com/android/documentsui/DocumentsAccess.java b/src/com/android/documentsui/DocumentsAccess.java
index 90c344a..3028f1b 100644
--- a/src/com/android/documentsui/DocumentsAccess.java
+++ b/src/com/android/documentsui/DocumentsAccess.java
@@ -16,7 +16,10 @@
 
 package com.android.documentsui;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
+
+import static android.content.ContentResolver.wrap;
+
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -47,7 +50,7 @@
     @Nullable DocumentInfo getArchiveDocument(Uri uri);
 
     boolean isDocumentUri(Uri uri);
-    @Nullable Path findDocumentPath(Uri uri) throws RemoteException;
+    @Nullable Path findDocumentPath(Uri uri) throws RemoteException, FileNotFoundException;
 
     List<DocumentInfo> getDocuments(String authority, List<String> docIds) throws RemoteException;
 
@@ -120,11 +123,11 @@
         }
 
         @Override
-        public Path findDocumentPath(Uri docUri) throws RemoteException {
+        public Path findDocumentPath(Uri docUri) throws RemoteException, FileNotFoundException {
             final ContentResolver resolver = mContext.getContentResolver();
             try (final ContentProviderClient client = DocumentsApplication
                     .acquireUnstableProviderOrThrow(resolver, docUri.getAuthority())) {
-                return DocumentsContract.findDocumentPath(client, docUri);
+                return DocumentsContract.findDocumentPath(wrap(client), docUri);
             }
         }
 
@@ -134,7 +137,7 @@
             try (ContentProviderClient client = DocumentsApplication.acquireUnstableProviderOrThrow(
                         resolver, parentDoc.derivedUri.getAuthority())) {
                 return DocumentsContract.createDocument(
-                        client, parentDoc.derivedUri, mimeType, displayName);
+                        wrap(client), parentDoc.derivedUri, mimeType, displayName);
             } catch (Exception e) {
                 Log.w(TAG, "Failed to create document", e);
                 return null;
diff --git a/src/com/android/documentsui/DocumentsApplication.java b/src/com/android/documentsui/DocumentsApplication.java
index 4c9c65f..65204b7 100644
--- a/src/com/android/documentsui/DocumentsApplication.java
+++ b/src/com/android/documentsui/DocumentsApplication.java
@@ -24,17 +24,23 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.om.OverlayManager;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.text.format.DateUtils;
+import android.util.Log;
 
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.clipping.ClipStorage;
 import com.android.documentsui.clipping.ClipStore;
 import com.android.documentsui.clipping.DocumentClipper;
+import com.android.documentsui.prefs.ScopedAccessLocalPreferences;
+import com.android.documentsui.queries.SearchHistoryManager;
 import com.android.documentsui.roots.ProvidersCache;
+import com.android.documentsui.theme.ThemeOverlayManager;
 
 public class DocumentsApplication extends Application {
+    private static final String TAG = "DocumentsApplication";
     private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS;
 
     private ProvidersCache mProviders;
@@ -80,13 +86,25 @@
         return ((DocumentsApplication) context.getApplicationContext()).mFileTypeLookup;
     }
 
+    private void onApplyOverlayFinish(boolean result) {
+        Log.d(TAG, "OverlayManager.setEnabled() result: " + result);
+    }
+
     @Override
     public void onCreate() {
         super.onCreate();
 
         final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        final OverlayManager om = getSystemService(OverlayManager.class);
         final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024;
 
+        if (om != null) {
+            new ThemeOverlayManager(om, getPackageName()).applyOverlays(this, true,
+                    this::onApplyOverlayFinish);
+        } else {
+            Log.w(TAG, "Can't obtain OverlayManager from System Service!");
+        }
+
         mProviders = new ProvidersCache(this);
         mProviders.updateAsync(false);
 
@@ -112,6 +130,9 @@
         final IntentFilter localeFilter = new IntentFilter();
         localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
         registerReceiver(mCacheReceiver, localeFilter);
+        ScopedAccessLocalPreferences.clearScopedAccessPreferences(this);
+
+        SearchHistoryManager.getInstance(getApplicationContext());
     }
 
     @Override
diff --git a/src/com/android/documentsui/DragAndDropManager.java b/src/com/android/documentsui/DragAndDropManager.java
index a80b35b..d49b689 100644
--- a/src/com/android/documentsui/DragAndDropManager.java
+++ b/src/com/android/documentsui/DragAndDropManager.java
@@ -16,14 +16,14 @@
 
 package com.android.documentsui;
 
-import android.annotation.IntDef;
-import android.annotation.Nullable;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
 import android.content.ClipData;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.DocumentsContract;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.view.DragEvent;
 import android.view.KeyEvent;
 import android.view.View;
@@ -31,6 +31,7 @@
 import com.android.documentsui.MenuManager.SelectionDetails;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
+import com.android.documentsui.base.MimeTypes;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.clipping.DocumentClipper;
 import com.android.documentsui.dirlist.IconHelper;
@@ -186,7 +187,7 @@
                     context.getApplicationContext(),
                     clipper,
                     new DragShadowBuilder(context),
-                    context.getDrawable(R.drawable.ic_doc_generic));
+                    IconUtils.loadMimeIcon(context, MimeTypes.GENERIC_TYPE));
         }
 
         @VisibleForTesting
@@ -439,9 +440,9 @@
             // is changed. The info about window should be passed in the localState then.
             // The localState could also be null for copying from Recents in single window
             // mode, but Recents doesn't offer this functionality (no directories).
-            Metrics.logUserAction(mContext,
-                    localState == null ? Metrics.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
-                            : Metrics.USER_ACTION_DRAG_N_DROP);
+            Metrics.logUserAction(
+                    localState == null ? MetricConsts.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
+                            : MetricConsts.USER_ACTION_DRAG_N_DROP);
 
             mClipper.copyFromClipData(dstStack, clipData, opType, callback);
         }
diff --git a/src/com/android/documentsui/dirlist/DragHoverListener.java b/src/com/android/documentsui/DragHoverListener.java
similarity index 75%
rename from src/com/android/documentsui/dirlist/DragHoverListener.java
rename to src/com/android/documentsui/DragHoverListener.java
index 7babe26..9994de5 100644
--- a/src/com/android/documentsui/dirlist/DragHoverListener.java
+++ b/src/com/android/documentsui/DragHoverListener.java
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.dirlist;
+package com.android.documentsui;
 
 import android.graphics.Point;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.view.DragEvent;
 import android.view.View;
 import android.view.View.OnDragListener;
+import android.widget.AbsListView;
 
-import com.android.documentsui.ItemDragListener;
 import com.android.documentsui.ItemDragListener.DragHost;
-import com.android.documentsui.selection.ViewAutoScroller;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
+import com.android.documentsui.ViewAutoScroller.ScrollHost;
+import com.android.documentsui.ViewAutoScroller.ScrollerCallbacks;
 
 import java.util.function.BooleanSupplier;
+import java.util.function.IntConsumer;
 import java.util.function.IntSupplier;
 import java.util.function.Predicate;
 
@@ -36,9 +36,9 @@
 
 /**
  * This class acts as a middle-man handler for potential auto-scrolling before passing the dragEvent
- * onto {@link DirectoryDragListener}.
+ * onto {@link ItemDragListener}.
  */
-class DragHoverListener implements OnDragListener {
+public class DragHoverListener implements OnDragListener {
 
     private final ItemDragListener<? extends DragHost> mDragHandler;
     private final IntSupplier mHeight;
@@ -47,12 +47,12 @@
     private final Runnable mDragScroller;
 
     /**
-     * Predicate to tests whether it's the scroll view ({@link DirectoryFragment#mRecView}) itself.
+     * Predicate to tests whether it's the scroll view itself.
      *
-     * {@link DragHoverListener} is used for both {@link DirectoryFragment#mRecView} and its
-     * children. When we decide whether it's in the scroll zone we need to obtain the coordinate
-     * relative to {@link DirectoryFragment#mRecView} so we need to transform the coordinate if the
-     * view that gets drag and drop events is a child of {@link DirectoryFragment#mRecView}.
+     * {@link DragHoverListener} is used for both the scroll view and its children.
+     * When we decide whether it's in the scroll zone we need to obtain the coordinate
+     * relative to container view so we need to transform the coordinate if the view
+     * that gets drag and drop events is a child of scroll view.
      */
     private final Predicate<View> mIsScrollView;
 
@@ -94,20 +94,37 @@
         mDragScroller = new ViewAutoScroller(scrollHost, scrollCallbacks);
     }
 
-    static DragHoverListener create(
+    public static DragHoverListener create(
+            ItemDragListener<? extends DragHost> dragHandler,
+            AbsListView scrollView) {
+        return create(dragHandler, scrollView, scrollView::scrollListBy);
+    }
+
+    public static DragHoverListener create(
             ItemDragListener<? extends DragHost> dragHandler,
             View scrollView) {
+        return create(
+                dragHandler,
+                scrollView,
+                (int dy) -> {
+                    scrollView.scrollBy(0, dy);
+                });
+    }
+
+    static DragHoverListener create(
+            ItemDragListener<? extends DragHost> dragHandler,
+            View scrollView,
+            IntConsumer scroller) {
 
         ScrollerCallbacks scrollCallbacks = new ScrollerCallbacks() {
             @Override
             public void scrollBy(int dy) {
-                scrollView.scrollBy(0, dy);
+                scroller.accept(dy);
             }
 
             @Override
             public void runAtNextFrame(Runnable r) {
                 scrollView.postOnAnimation(r);
-
             }
 
             @Override
@@ -116,15 +133,13 @@
             }
         };
 
-        DragHoverListener listener = new DragHoverListener(
+        return new DragHoverListener(
                 dragHandler,
                 scrollView::getHeight,
                 (view) -> (scrollView == view),
                 () -> scrollView.canScrollVertically(-1),
                 () -> scrollView.canScrollVertically(1),
                 scrollCallbacks);
-
-        return listener;
     }
 
     @Override
@@ -157,9 +172,9 @@
     }
 
     private Point transformToScrollViewCoordinate(View v, float x, float y) {
-        // Check if v is the RecyclerView itself. If not we need to transform the coordinate to
-        // relative to the RecyclerView because we need to test the scroll zone in the coordinate
-        // relative to the RecyclerView; if yes we don't need to transform coordinates.
+        // Check if v is the scroll view itself. If not we need to transform the coordinate to
+        // relative to the scroll view because we need to test the scroll zone in the coordinate
+        // relative to the scroll view; if yes we don't need to transform coordinates.
         final boolean isScrollView = mIsScrollView.test(v);
         final float offsetX = isScrollView ? 0 : v.getX();
         final float offsetY = isScrollView ? 0 : v.getY();
@@ -179,4 +194,4 @@
                 && mCanScrollDown.getAsBoolean();
         return shouldScrollUp || shouldScrollDown;
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/DrawerController.java b/src/com/android/documentsui/DrawerController.java
index 1a69363..e599655 100644
--- a/src/com/android/documentsui/DrawerController.java
+++ b/src/com/android/documentsui/DrawerController.java
@@ -18,21 +18,18 @@
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.annotation.IntDef;
 import android.app.Activity;
-import android.support.annotation.ColorRes;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.DrawerLayout.DrawerListener;
 import android.util.Log;
 import android.view.View;
-import android.widget.Toolbar;
+
+import androidx.annotation.ColorRes;
+import androidx.appcompat.widget.Toolbar;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.drawerlayout.widget.DrawerLayout.DrawerListener;
+import androidx.legacy.app.ActionBarDrawerToggle;
 
 import com.android.documentsui.base.Display;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * A facade over the various pieces comprising "roots fragment in a Drawer".
  *
@@ -60,7 +57,6 @@
 
         View drawer = activity.findViewById(R.id.drawer_roots);
         Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
-
         drawer.getLayoutParams().width = calculateDrawerWidth(activity);
 
         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
@@ -134,7 +130,7 @@
         public void setDropTargetHighlight(View v, boolean highlight) {
             assert (v.getId() == R.id.drawer_edge);
 
-            @ColorRes int id = highlight ? R.color.item_doc_background_selected :
+            @ColorRes int id = highlight ? R.color.secondary :
                 android.R.color.transparent;
             v.setBackgroundColor(id);
         }
diff --git a/src/com/android/documentsui/DropBadgeView.java b/src/com/android/documentsui/DropBadgeView.java
index 6f71d01..552e2ec 100644
--- a/src/com/android/documentsui/DropBadgeView.java
+++ b/src/com/android/documentsui/DropBadgeView.java
@@ -17,6 +17,7 @@
 package com.android.documentsui;
 
 import com.android.documentsui.DragAndDropManager.State;
+import com.android.documentsui.base.MimeTypes;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -45,8 +46,7 @@
         final int iconSize = context.getResources().getDimensionPixelSize(R.dimen.root_icon_size);
 
         Drawable okBadge = context.getResources().getDrawable(R.drawable.drop_badge_states, null);
-        Drawable defaultIcon = context.getResources()
-                .getDrawable(R.drawable.ic_doc_generic, null);
+        Drawable defaultIcon = IconUtils.loadMimeIcon(context, MimeTypes.GENERIC_TYPE);
 
         Drawable[] list = {defaultIcon, okBadge};
         mBackground = new LayerDrawable(list);
diff --git a/src/com/android/documentsui/DropdownBreadcrumb.java b/src/com/android/documentsui/DropdownBreadcrumb.java
index 7f5e5f3..8e9b07f 100644
--- a/src/com/android/documentsui/DropdownBreadcrumb.java
+++ b/src/com/android/documentsui/DropdownBreadcrumb.java
@@ -21,6 +21,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.Spinner;
@@ -73,6 +74,14 @@
                     @Override
                     public void onNothingSelected(AdapterView<?> parent) {}
                 });
+        setAccessibilityDelegate(new AccessibilityDelegate() {
+            @Override
+            public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
+                if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SELECTED) {
+                    super.onInitializeAccessibilityEvent(host, event);
+                }
+            }
+        });
     }
 
     @Override
diff --git a/src/com/android/documentsui/DummySelectionTracker.java b/src/com/android/documentsui/DummySelectionTracker.java
new file mode 100644
index 0000000..49b9ad9
--- /dev/null
+++ b/src/com/android/documentsui/DummySelectionTracker.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2018 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.documentsui;
+
+import android.os.Bundle;
+
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.Selection;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
+
+import java.util.Set;
+
+/**
+ * A dummy SelectionTracker used by DocsSelectionHelper before a real SelectionTracker has been
+ * initialized by DirectoryFragment.
+ */
+public class DummySelectionTracker<K> extends SelectionTracker<K> {
+
+    @Override
+    public void addObserver(SelectionObserver observer) {
+    }
+
+    @Override
+    public boolean hasSelection() {
+        return false;
+    }
+
+    @Override
+    public Selection<K> getSelection() {
+        return new MutableSelection<K>();
+    }
+
+    @Override
+    public void copySelection(MutableSelection<K> dest) {
+    }
+
+    @Override
+    public boolean isSelected(K key) {
+        return false;
+    }
+
+    @Override
+    public void restoreSelection(Selection<K> selection) {
+    }
+
+    @Override
+    public boolean clearSelection() {
+        return false;
+    }
+
+    @Override
+    public boolean setItemsSelected(Iterable<K> keys, boolean selected) {
+        return false;
+    }
+
+    @Override
+    public boolean select(K key) {
+        return false;
+    }
+
+    @Override
+    public boolean deselect(K key) {
+        return false;
+    }
+
+    @Override
+    protected AdapterDataObserver getAdapterDataObserver() {
+        return null;
+    }
+
+    @Override
+    public void startRange(int position) {
+    }
+
+    @Override
+    public void extendRange(int position) {
+    }
+
+    @Override
+    public void endRange() {
+    }
+
+    @Override
+    public boolean isRangeActive() {
+        return false;
+    }
+
+    @Override
+    public void anchorRange(int position) {
+    }
+
+    @Override
+    public void extendProvisionalRange(int position) {
+    }
+
+    @Override
+    public void setProvisionalSelection(Set<K> newSelection) {
+    }
+
+    @Override
+    public void clearProvisionalSelection() {
+    }
+
+    @Override
+    public void mergeProvisionalSelection() {
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle state) {
+    }
+
+    @Override
+    public void onRestoreInstanceState(Bundle state) {
+    }
+
+}
diff --git a/src/com/android/documentsui/FileTypeMap.java b/src/com/android/documentsui/FileTypeMap.java
index 2f031cb..fbad764 100644
--- a/src/com/android/documentsui/FileTypeMap.java
+++ b/src/com/android/documentsui/FileTypeMap.java
@@ -16,150 +16,24 @@
 
 package com.android.documentsui;
 
-import android.annotation.StringRes;
+import android.content.ContentResolver;
 import android.content.Context;
-import android.content.res.Resources;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
 
 import com.android.documentsui.base.Lookup;
-import com.android.documentsui.base.MimeTypes;
-
-import libcore.net.MimeMap;
-
-import java.util.HashMap;
 
 /**
  * A map from mime type to user friendly type string.
  */
 public class FileTypeMap implements Lookup<String, String> {
-
-    private static final String TAG = "FileTypeMap";
-
-    private final Resources mRes;
-
-    private final SparseArray<Integer> mMediaTypeStringMap = new SparseArray<>();
-
-    private final HashMap<String, Integer> mFileTypeMap = new HashMap<>();
-    private final HashMap<String, String> mArchiveTypeMap = new HashMap<>();
-    private final HashMap<String, Integer> mSpecialMediaMimeType = new HashMap<>();
+    private final ContentResolver mResolver;
 
     FileTypeMap(Context context) {
-        mRes = context.getResources();
-
-        // Mapping from generic media type string to extension media type string
-        mMediaTypeStringMap.put(R.string.video_file_type, R.string.video_extension_file_type);
-        mMediaTypeStringMap.put(R.string.audio_file_type, R.string.audio_extension_file_type);
-        mMediaTypeStringMap.put(R.string.image_file_type, R.string.image_extension_file_type);
-
-        // Common file types
-        mFileTypeMap.put(MimeTypes.APK_TYPE, R.string.apk_file_type);
-        mFileTypeMap.put("text/plain", R.string.txt_file_type);
-        mFileTypeMap.put("text/html", R.string.html_file_type);
-        mFileTypeMap.put("application/xhtml+xml", R.string.html_file_type);
-        mFileTypeMap.put("application/pdf", R.string.pdf_file_type);
-
-        // MS file types
-        mFileTypeMap.put("application/msword", R.string.word_file_type);
-        mFileTypeMap.put(
-                "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
-                R.string.word_file_type);
-        mFileTypeMap.put("application/vnd.ms-powerpoint", R.string.ppt_file_type);
-        mFileTypeMap.put(
-                "application/vnd.openxmlformats-officedocument.presentationml.presentation",
-                R.string.ppt_file_type);
-        mFileTypeMap.put("application/vnd.ms-excel", R.string.excel_file_type);
-        mFileTypeMap.put(
-                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
-                R.string.excel_file_type);
-
-        // Google doc types
-        mFileTypeMap.put("application/vnd.google-apps.document", R.string.gdoc_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.spreadsheet", R.string.gsheet_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.presentation", R.string.gslides_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.drawing", R.string.gdraw_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.fusiontable", R.string.gtable_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.form", R.string.gform_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.map", R.string.gmap_file_type);
-        mFileTypeMap.put("application/vnd.google-apps.sites", R.string.gsite_file_type);
-
-        // Directory type
-        mFileTypeMap.put("vnd.android.document/directory", R.string.directory_type);
-
-        // Archive types
-        mArchiveTypeMap.put("application/rar", "RAR");
-        mArchiveTypeMap.put("application/zip", "Zip");
-        mArchiveTypeMap.put("application/x-tar", "Tar");
-        mArchiveTypeMap.put("application/gzip", "Gzip");
-        mArchiveTypeMap.put("application/x-7z-compressed", "7z");
-        mArchiveTypeMap.put("application/x-rar-compressed", "RAR");
-
-        // Special media mime types
-        mSpecialMediaMimeType.put("application/ogg", R.string.audio_file_type);
-        mSpecialMediaMimeType.put("application/x-flac", R.string.audio_file_type);
+        mResolver = context.getContentResolver();
     }
 
     @Override
     public String lookup(String mimeType) {
-        if (mFileTypeMap.containsKey(mimeType)) {
-            return getPredefinedFileTypeString(mimeType);
-        }
-
-        if (mArchiveTypeMap.containsKey(mimeType)) {
-            return buildArchiveTypeString(mimeType);
-        }
-
-        if (mSpecialMediaMimeType.containsKey(mimeType)) {
-            int genericType = mSpecialMediaMimeType.get(mimeType);
-            return getFileTypeString(mimeType, mMediaTypeStringMap.get(genericType), genericType);
-        }
-
-        final String[] type = MimeTypes.splitMimeType(mimeType);
-        if (type == null) {
-            Log.w(TAG, "Unexpected mime type " + mimeType);
-            return getGenericFileTypeString();
-        }
-
-        switch (type[0]) {
-            case MimeTypes.IMAGE_PREFIX:
-                return getFileTypeString(
-                        mimeType, R.string.image_extension_file_type, R.string.image_file_type);
-            case MimeTypes.AUDIO_PREFIX:
-                return getFileTypeString(
-                        mimeType, R.string.audio_extension_file_type, R.string.audio_file_type);
-            case MimeTypes.VIDEO_PREFIX:
-                return getFileTypeString(
-                        mimeType, R.string.video_extension_file_type, R.string.video_file_type);
-            default:
-                return getFileTypeString(
-                        mimeType, R.string.generic_extention_file_type, R.string.generic_file_type);
-        }
-    }
-
-    private String buildArchiveTypeString(String mimeType) {
-        final String archiveType = mArchiveTypeMap.get(mimeType);
-
-        assert(!TextUtils.isEmpty(archiveType));
-
-        final String format = mRes.getString(R.string.archive_file_type);
-        return String.format(format, archiveType);
-    }
-
-    private String getPredefinedFileTypeString(String mimeType) {
-        return mRes.getString(mFileTypeMap.get(mimeType));
-    }
-
-    private String getFileTypeString(
-            String mimeType, @StringRes int formatStringId, @StringRes int defaultStringId) {
-        final String extension = MimeMap.getDefault().guessExtensionFromMimeType(mimeType);
-
-        return TextUtils.isEmpty(extension)
-                ? mRes.getString(defaultStringId)
-                : String.format(mRes.getString(formatStringId), extension.toUpperCase());
-    }
-
-    private String getGenericFileTypeString() {
-        return mRes.getString(R.string.generic_file_type);
+        if (mimeType == null) return null;
+        return String.valueOf(mResolver.getTypeInfo(mimeType).getLabel());
     }
 }
diff --git a/src/com/android/documentsui/FocusManager.java b/src/com/android/documentsui/FocusManager.java
index 676ffa2..9d9f4c7 100644
--- a/src/com/android/documentsui/FocusManager.java
+++ b/src/com/android/documentsui/FocusManager.java
@@ -18,17 +18,15 @@
 
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.internal.util.Preconditions.checkNotNull;
+import static androidx.core.util.Preconditions.checkNotNull;
 
-import android.annotation.ColorRes;
-import android.annotation.Nullable;
+import androidx.annotation.ColorRes;
+import androidx.annotation.Nullable;
 import android.database.Cursor;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemClock;
 import android.provider.DocumentsContract.Document;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
 import android.text.Editable;
 import android.text.Spannable;
 import android.text.method.KeyListener;
@@ -40,6 +38,13 @@
 import android.view.View;
 import android.widget.TextView;
 
+import androidx.recyclerview.selection.FocusDelegate;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.documentsui.Model.Update;
 import com.android.documentsui.base.EventListener;
 import com.android.documentsui.base.Events;
 import com.android.documentsui.base.Features;
@@ -47,21 +52,22 @@
 import com.android.documentsui.dirlist.DocumentHolder;
 import com.android.documentsui.dirlist.DocumentsAdapter;
 import com.android.documentsui.dirlist.FocusHandler;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.Model.Update;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
 
-public final class FocusManager implements FocusHandler {
+/**
+ * The implementation to handle focus and keyboard driven navigation.
+ */
+public final class FocusManager extends FocusDelegate<String> implements FocusHandler {
     private static final String TAG = "FocusManager";
 
     private final ContentScope mScope = new ContentScope();
 
     private final Features mFeatures;
-    private final SelectionHelper mSelectionMgr;
+    private final SelectionTracker<String> mSelectionMgr;
     private final DrawerController mDrawer;
     private final Procedure mRootsFocuser;
     private final TitleSearchHelper mSearchHelper;
@@ -70,7 +76,7 @@
 
     public FocusManager(
             Features features,
-            SelectionHelper selectionMgr,
+            SelectionTracker<String> selectionMgr,
             DrawerController drawer,
             Procedure rootsFocuser,
             @ColorRes int color) {
@@ -129,15 +135,17 @@
     @Override
     public void onFocusChange(View v, boolean hasFocus) {
         // Remember focus events on items.
-        if (hasFocus && v.getParent() == mScope.view) {
+        if (hasFocus && mScope.isValid() && v.getParent() == mScope.view) {
             mScope.lastFocusPosition = mScope.view.getChildAdapterPosition(v);
         }
     }
 
     @Override
     public boolean focusDirectoryList() {
-        if (mScope.adapter.getItemCount() == 0) {
-            if (DEBUG) Log.v(TAG, "Nothing to focus.");
+        if (!mScope.isValid() || mScope.adapter.getItemCount() == 0) {
+            if (DEBUG) {
+                Log.v(TAG, "Nothing to focus.");
+            }
             return false;
         }
 
@@ -146,7 +154,9 @@
         // vs. Cut focused
         // item)
         if (mSelectionMgr.hasSelection()) {
-            if (DEBUG) Log.v(TAG, "Existing selection found. No focus will be done.");
+            if (DEBUG) {
+                Log.v(TAG, "Existing selection found. No focus will be done.");
+            }
             return false;
         }
 
@@ -180,7 +190,9 @@
 
     @Override
     public void clearFocus() {
-        mScope.view.clearFocus();
+        if (mScope.isValid()) {
+            mScope.view.clearFocus();
+        }
     }
 
     /*
@@ -190,6 +202,12 @@
      */
     @Override
     public void focusDocument(String modelId) {
+        if (!mScope.isValid()) {
+            if (DEBUG) {
+                Log.v(TAG, "Invalid mScope. No focus will be done.");
+            }
+            return;
+        }
         int pos = mScope.adapter.getAdapterPosition(modelId);
         if (pos != -1 && mScope.view.findViewHolderForAdapterPosition(pos) != null) {
             focusItem(pos);
@@ -199,7 +217,12 @@
     }
 
     @Override
-    public int getFocusPosition() {
+    public void focusItem(ItemDetails<String> item) {
+        focusDocument(item.getSelectionKey());
+    }
+
+    @Override
+    public int getFocusedPosition() {
         return mScope.lastFocusPosition;
     }
 
@@ -663,5 +686,9 @@
 
         private @Nullable String pendingFocusId;
         private int lastFocusPosition = RecyclerView.NO_POSITION;
+
+        boolean isValid() {
+            return (view != null && model != null);
+        }
     }
 }
diff --git a/src/com/android/documentsui/GlobalSearchLoader.java b/src/com/android/documentsui/GlobalSearchLoader.java
new file mode 100644
index 0000000..073b3d0
--- /dev/null
+++ b/src/com/android/documentsui/GlobalSearchLoader.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 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.documentsui;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+
+import androidx.annotation.NonNull;
+
+import com.android.documentsui.base.Lookup;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.State;
+import com.android.documentsui.roots.ProvidersAccess;
+import com.android.documentsui.roots.RootCursorWrapper;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/*
+ * The class to query multiple roots support {@link DocumentsContract.Root#FLAG_LOCAL_ONLY}
+ * and {@link DocumentsContract.Root#FLAG_SUPPORTS_SEARCH} from
+ * {@link android.provider.DocumentsProvider}.
+ */
+public class GlobalSearchLoader extends MultiRootDocumentsLoader {
+    private final Bundle mQueryArgs;
+
+    /*
+     * Create the loader to query multiple roots support
+     * {@link DocumentsContract.Root#FLAG_LOCAL_ONLY} and
+     * {@link DocumentsContract.Root#FLAG_SUPPORTS_SEARCH} from
+     * {@link android.provider.DocumentsProvider}.
+     *
+     * @param context the context
+     * @param providers the providers
+     * @param state current state
+     * @param features the feature flags
+     * @param executors the executors of authorities
+     * @param fileTypeMap the map of mime types and file types
+     * @param queryArgs the bundle of query arguments
+     */
+    GlobalSearchLoader(Context context, ProvidersAccess providers, State state,
+            Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap,
+            @NonNull Bundle queryArgs) {
+        super(context, providers, state, executors, fileTypeMap);
+        mQueryArgs = queryArgs;
+    }
+
+    @Override
+    protected boolean shouldIgnoreRoot(RootInfo root) {
+        // Only support local search in GlobalSearchLoader
+        if (!root.isLocalOnly() || !root.supportsSearch()) {
+            return true;
+        }
+
+        // If the value of showAdvanced is true,
+        // don't query media roots and downloads root to avoid showing
+        // duplicated files.
+        if (mState.showAdvanced && (root.isLibrary() || root.isDownloads())) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected QueryTask getQueryTask(String authority, List<RootInfo> rootInfos) {
+        return new SearchTask(authority, rootInfos);
+    }
+
+    private class SearchTask extends QueryTask {
+
+        public SearchTask(String authority, List<RootInfo> rootInfos) {
+            super(authority, rootInfos);
+        }
+
+        @Override
+        protected void addQueryArgs(@NonNull Bundle queryArgs) {
+            queryArgs.putBoolean(DocumentsContract.QUERY_ARG_EXCLUDE_MEDIA, true);
+            queryArgs.putAll(mQueryArgs);
+        }
+
+        @Override
+        protected Uri getQueryUri(RootInfo rootInfo) {
+            // For the new querySearchDocuments, we put the query string into queryArgs.
+            // Use the empty string to build the query uri.
+            return DocumentsContract.buildSearchDocumentsUri(authority,
+                    rootInfo.rootId, "" /* query */);
+        }
+
+        @Override
+        protected RootCursorWrapper generateResultCursor(RootInfo rootInfo, Cursor oriCursor) {
+            return new RootCursorWrapper(authority, rootInfo.rootId, oriCursor, -1 /* maxCount */);
+        }
+    }
+}
diff --git a/src/com/android/documentsui/GridItemThumbnail.java b/src/com/android/documentsui/GridItemThumbnail.java
index 38d6d72..6348148 100644
--- a/src/com/android/documentsui/GridItemThumbnail.java
+++ b/src/com/android/documentsui/GridItemThumbnail.java
@@ -17,6 +17,8 @@
 package com.android.documentsui;
 
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
@@ -34,6 +36,10 @@
 
     public GridItemThumbnail(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        TypedArray ta = context.obtainStyledAttributes(R.styleable.GridItem);
+        ColorStateList color = ta.getColorStateList(R.styleable.GridItem_gridItemTint);
+        ta.recycle();
+        setImageTintList(color);
     }
 
     @Override
diff --git a/src/com/android/documentsui/HorizontalBreadcrumb.java b/src/com/android/documentsui/HorizontalBreadcrumb.java
index 2a3b82d..6a7cce1 100644
--- a/src/com/android/documentsui/HorizontalBreadcrumb.java
+++ b/src/com/android/documentsui/HorizontalBreadcrumb.java
@@ -17,8 +17,6 @@
 package com.android.documentsui;
 
 import android.content.Context;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
 import android.view.GestureDetector;
 import android.view.KeyEvent;
@@ -28,6 +26,9 @@
 import android.view.ViewGroup;
 import android.widget.ImageView;
 
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.documentsui.NavigationViewManager.Breadcrumb;
 import com.android.documentsui.NavigationViewManager.Environment;
 import com.android.documentsui.base.DocumentInfo;
@@ -77,7 +78,7 @@
         // for more details on how we are routing these a11y events.
         setAccessibilityDelegateCompat(
                 new AccessibilityEventRouter(this,
-                        (View child) -> onAccessibilityClick(child)));
+                        (View child) -> onAccessibilityClick(child), null));
 
         setLayoutManager(mLayoutManager);
         addOnItemTouchListener(new ClickListener(getContext(), this::onSingleTapUp));
diff --git a/src/com/android/documentsui/IconUtils.java b/src/com/android/documentsui/IconUtils.java
index 7b6678d..46d0321 100644
--- a/src/com/android/documentsui/IconUtils.java
+++ b/src/com/android/documentsui/IconUtils.java
@@ -20,9 +20,10 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.graphics.drawable.Drawable;
-import android.provider.DocumentsContract.Document;
 import android.util.TypedValue;
 
+import com.android.documentsui.base.MimeTypes;
+
 public class IconUtils {
     public static Drawable loadPackageIcon(Context context, String authority, int icon) {
         if (icon != 0) {
@@ -41,19 +42,26 @@
 
     public static Drawable loadMimeIcon(
             Context context, String mimeType, String authority, String docId, int mode) {
-        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-            return context.getDrawable(R.drawable.ic_doc_folder);
-        }
-
         return loadMimeIcon(context, mimeType);
     }
 
+    /**
+     * Load mime type drawable from system MimeIconUtils.
+     * @param context activity context to obtain resource
+     * @param mimeType specific mime type string of file
+     * @return drawable of mime type files from system default
+     */
     public static Drawable loadMimeIcon(Context context, String mimeType) {
-        return context.getContentResolver().getTypeDrawable(mimeType);
+        if (mimeType == null) return null;
+        return context.getContentResolver().getTypeInfo(mimeType).getIcon().loadDrawable(context);
     }
 
     public static Drawable applyTintColor(Context context, int drawableId, int tintColorId) {
         final Drawable icon = context.getDrawable(drawableId);
+        return applyTintColor(context, icon, tintColorId);
+    }
+
+    public static Drawable applyTintColor(Context context, Drawable icon, int tintColorId) {
         icon.mutate();
         icon.setTintList(context.getColorStateList(tintColorId));
         return icon;
diff --git a/src/com/android/documentsui/Injector.java b/src/com/android/documentsui/Injector.java
index 7f9edd4..d6c6312 100644
--- a/src/com/android/documentsui/Injector.java
+++ b/src/com/android/documentsui/Injector.java
@@ -18,25 +18,25 @@
 import static java.lang.annotation.ElementType.FIELD;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
 import android.view.MenuItem;
 
+import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.documentsui.MenuManager.SelectionDetails;
 import com.android.documentsui.base.DebugHelper;
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.dirlist.DocsStableIdProvider;
-import com.android.documentsui.dirlist.DocumentsAdapter;
+import com.android.documentsui.dirlist.AppsRowManager;
+import com.android.documentsui.picker.PickResult;
 import com.android.documentsui.prefs.ScopedPreferences;
 import com.android.documentsui.queries.SearchViewManager;
-import com.android.documentsui.selection.ContentLock;
-import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.ui.DialogController;
 import com.android.documentsui.ui.MessageBuilder;
-import com.android.internal.annotations.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
@@ -58,6 +58,9 @@
     public MenuManager menuManager;
     public DialogController dialogs;
     public SearchViewManager searchManager;
+    public AppsRowManager appsRowManager;
+
+    public PickResult pickResult;
 
     public final DebugHelper debugHelper;
 
@@ -120,9 +123,8 @@
         return focusManager.reset(view, model);
     }
 
-    public SelectionHelper getSelectionManager(
-            DocumentsAdapter adapter, SelectionHelper.SelectionPredicate canSetState) {
-        return selectionMgr.reset(adapter, new DocsStableIdProvider(adapter), canSetState);
+    public void updateSharedSelectionTracker(SelectionTracker<String> selectionTracker) {
+        selectionMgr.reset(selectionTracker);
     }
 
     public final ActionModeController getActionModeController(
diff --git a/src/com/android/documentsui/ItemDragListener.java b/src/com/android/documentsui/ItemDragListener.java
index cee5e91..530b550 100644
--- a/src/com/android/documentsui/ItemDragListener.java
+++ b/src/com/android/documentsui/ItemDragListener.java
@@ -24,7 +24,7 @@
 import android.view.View.OnDragListener;
 
 import com.android.documentsui.ItemDragListener.DragHost;
-import com.android.internal.annotations.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 
 import java.util.Timer;
 import java.util.TimerTask;
@@ -63,6 +63,10 @@
 
     @Override
     public boolean onDrag(final View v, DragEvent event) {
+        if (!mDragHost.canHandleDragEvent(v)) {
+            return false;
+        }
+
         switch (event.getAction()) {
             case DragEvent.ACTION_DRAG_STARTED:
                 return true;
@@ -193,5 +197,13 @@
          * Notifies when the drag and drop has ended.
          */
         void onDragEnded();
+
+        /**
+         * Whether drag events can dispatch to the view.
+         * @param v the view being to receive drag events
+         */
+        default boolean canHandleDragEvent(View v) {
+            return true;
+        }
     }
 }
diff --git a/src/com/android/documentsui/LoadDocStackTask.java b/src/com/android/documentsui/LoadDocStackTask.java
index af10693..404bb1b 100644
--- a/src/com/android/documentsui/LoadDocStackTask.java
+++ b/src/com/android/documentsui/LoadDocStackTask.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.app.Activity;
 import android.net.Uri;
 import android.provider.DocumentsContract;
diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java
index 705c35a..5fcbe7b 100644
--- a/src/com/android/documentsui/MenuManager.java
+++ b/src/com/android/documentsui/MenuManager.java
@@ -16,13 +16,15 @@
 
 package com.android.documentsui;
 
-import android.app.Fragment;
 import android.view.KeyboardShortcutGroup;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Menus;
 import com.android.documentsui.base.RootInfo;
@@ -30,17 +32,19 @@
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.sidebar.RootsFragment;
-import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.List;
 import java.util.function.IntFunction;
 
 public abstract class MenuManager {
+    private final static String TAG = "MenuManager";
 
     final protected SearchViewManager mSearchManager;
     final protected State mState;
     final protected DirectoryDetails mDirDetails;
 
+    protected Menu mOptionMenu;
+
     public MenuManager(
             SearchViewManager searchManager,
             State displayState,
@@ -52,11 +56,11 @@
 
     /** @see ActionModeController */
     public void updateActionMenu(Menu menu, SelectionDetails selection) {
-        updateOpenInActionMode(menu.findItem(R.id.action_menu_open), selection);
         updateOpenWith(menu.findItem(R.id.action_menu_open_with), selection);
         updateDelete(menu.findItem(R.id.action_menu_delete), selection);
         updateShare(menu.findItem(R.id.action_menu_share), selection);
         updateRename(menu.findItem(R.id.action_menu_rename), selection);
+        updateSelect(menu.findItem(R.id.action_menu_select), selection);
         updateSelectAll(menu.findItem(R.id.action_menu_select_all));
         updateMoveTo(menu.findItem(R.id.action_menu_move_to), selection);
         updateCopyTo(menu.findItem(R.id.action_menu_copy_to), selection);
@@ -64,24 +68,40 @@
         updateExtractTo(menu.findItem(R.id.action_menu_extract_to), selection);
         updateInspect(menu.findItem(R.id.action_menu_inspect), selection);
         updateViewInOwner(menu.findItem(R.id.action_menu_view_in_owner), selection);
+        updateSort(menu.findItem(R.id.action_menu_sort));
 
         Menus.disableHiddenItems(menu);
     }
 
     /** @see BaseActivity#onPrepareOptionsMenu */
     public void updateOptionMenu(Menu menu) {
-        updateCreateDir(menu.findItem(R.id.option_menu_create_dir));
-        updateSettings(menu.findItem(R.id.option_menu_settings));
-        updateSelectAll(menu.findItem(R.id.option_menu_select_all));
-        updateNewWindow(menu.findItem(R.id.option_menu_new_window));
-        updateModePicker(menu.findItem(R.id.option_menu_grid),
-                menu.findItem(R.id.option_menu_list));
-        updateAdvanced(menu.findItem(R.id.option_menu_advanced));
-        updateDebug(menu.findItem(R.id.option_menu_debug));
-        updateInspect(menu.findItem(R.id.option_menu_inspect));
-        Menus.disableHiddenItems(menu);
+        mOptionMenu = menu;
+        updateOptionMenu();
     }
 
+    public void updateOptionMenu() {
+        if (mOptionMenu == null) {
+            return;
+        }
+        updateCreateDir(mOptionMenu.findItem(R.id.option_menu_create_dir));
+        updateSettings(mOptionMenu.findItem(R.id.option_menu_settings));
+        updateSelectAll(mOptionMenu.findItem(R.id.option_menu_select_all));
+        updateNewWindow(mOptionMenu.findItem(R.id.option_menu_new_window));
+        updateAdvanced(mOptionMenu.findItem(R.id.option_menu_advanced));
+        updateDebug(mOptionMenu.findItem(R.id.option_menu_debug));
+        updateInspect(mOptionMenu.findItem(R.id.option_menu_inspect));
+        updateSort(mOptionMenu.findItem(R.id.option_menu_sort));
+
+        Menus.disableHiddenItems(mOptionMenu);
+        mSearchManager.updateMenu();
+    }
+
+    public void updateSubMenu(Menu menu) {
+        updateModePicker(menu.findItem(R.id.sub_menu_grid), menu.findItem(R.id.sub_menu_list));
+    }
+
+    public void updateModel(Model model) {}
+
     /**
      * Called when we needs {@link MenuManager} to ask Android to show context menu for us.
      * {@link MenuManager} can choose to defeat this request.
@@ -228,6 +248,10 @@
                 ? R.string.menu_advanced_hide : R.string.menu_advanced_show);
     }
 
+    protected void updateSort(MenuItem sort) {
+        sort.setVisible(true);
+    }
+
     protected void updateDebug(MenuItem debug) {
         debug.setVisible(mState.debugMode);
     }
@@ -248,8 +272,8 @@
         newWindow.setVisible(false);
     }
 
-    protected void updateOpenInActionMode(MenuItem open, SelectionDetails selectionDetails) {
-        open.setVisible(false);
+    protected void updateSelect(MenuItem select, SelectionDetails selectionDetails) {
+        select.setVisible(false);
     }
 
     protected void updateOpenWith(MenuItem openWith, SelectionDetails selectionDetails) {
@@ -321,8 +345,10 @@
         pasteInto.setVisible(false);
     }
 
-    protected abstract void updateOpenInContextMenu(
-            MenuItem open, SelectionDetails selectionDetails);
+    protected void updateOpenInContextMenu(MenuItem open, SelectionDetails selectionDetails) {
+        open.setVisible(false);
+    }
+
     protected abstract void updateSelectAll(MenuItem selectAll);
     protected abstract void updateCreateDir(MenuItem createDir);
 
@@ -375,7 +401,7 @@
         }
 
         public boolean isInRecents() {
-            return mActivity.getCurrentDirectory() == null;
+            return mActivity.isInRecents();
         }
 
         public boolean canCreateDirectory() {
@@ -383,7 +409,7 @@
         }
 
         public boolean canInspectDirectory() {
-            return mActivity.canInspectDirectory();
+            return mActivity.canInspectDirectory() && !isInRecents();
         }
     }
 }
diff --git a/src/com/android/documentsui/MetricConsts.java b/src/com/android/documentsui/MetricConsts.java
new file mode 100644
index 0000000..f95f6e5
--- /dev/null
+++ b/src/com/android/documentsui/MetricConsts.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2019 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.documentsui;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * All constants are based on the enums in
+ * frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto.
+ */
+public class MetricConsts {
+
+    // Codes representing different root types.
+    public static final int ROOT_UNKNOWN = 0;
+    public static final int ROOT_NONE = 1;
+    public static final int ROOT_OTHER_DOCS_PROVIDER = 2;
+    public static final int ROOT_AUDIO = 3;
+    public static final int ROOT_DEVICE_STORAGE = 4;
+    public static final int ROOT_DOWNLOADS = 5;
+    public static final int ROOT_HOME = 6;
+    public static final int ROOT_IMAGES = 7;
+    public static final int ROOT_RECENTS = 8;
+    public static final int ROOT_VIDEOS = 9;
+    public static final int ROOT_MTP = 10;
+    public static final int ROOT_THIRD_PARTY_APP = 11;
+
+    @IntDef(flag = true, value = {
+            ROOT_UNKNOWN,
+            ROOT_NONE,
+            ROOT_OTHER_DOCS_PROVIDER,
+            ROOT_AUDIO,
+            ROOT_DEVICE_STORAGE,
+            ROOT_DOWNLOADS,
+            ROOT_HOME,
+            ROOT_IMAGES,
+            ROOT_RECENTS,
+            ROOT_VIDEOS,
+            ROOT_MTP,
+            ROOT_THIRD_PARTY_APP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Root {
+    }
+
+    // Codes representing different mime types.
+    static final int MIME_UNKNOWN = 0;
+    static final int MIME_NONE = 1; // null mime
+    static final int MIME_ANY = 2; // */*
+    static final int MIME_APPLICATION = 3; // application/*
+    static final int MIME_AUDIO = 4; // audio/*
+    static final int MIME_IMAGE = 5; // image/*
+    static final int MIME_MESSAGE = 6; // message/*
+    static final int MIME_MULTIPART = 7; // multipart/*
+    static final int MIME_TEXT = 8; // text/*
+    static final int MIME_VIDEO = 9; // video/*
+    static final int MIME_OTHER = 10; // anything not enumerated below
+
+    @IntDef(flag = true, value = {
+            MIME_UNKNOWN,
+            MIME_NONE,
+            MIME_ANY,
+            MIME_APPLICATION,
+            MIME_AUDIO,
+            MIME_IMAGE,
+            MIME_MESSAGE,
+            MIME_MULTIPART,
+            MIME_TEXT,
+            MIME_VIDEO,
+            MIME_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Mime {
+    }
+
+    public static final int UNKNOWN_SCOPE = 0;
+    public static final int FILES_SCOPE = 1;
+    public static final int PICKER_SCOPE = 2;
+
+    // Codes representing different scopes(FILE/PICKER mode).
+    @IntDef({UNKNOWN_SCOPE, FILES_SCOPE, PICKER_SCOPE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ContextScope {
+    }
+
+    // Codes representing different kinds of file operations.
+    static final int FILEOP_UNKNOWN = 0;
+    static final int FILEOP_OTHER = 1; // any file operation not listed below
+    static final int FILEOP_COPY = 2;
+    static final int FILEOP_COPY_INTRA_PROVIDER = 3; // Copy within a provider
+    static final int FILEOP_COPY_SYSTEM_PROVIDER = 4; // Copy to a system provider.
+    static final int FILEOP_COPY_EXTERNAL_PROVIDER = 5; // Copy to a 3rd-party provider.
+    static final int FILEOP_MOVE = 6;
+    static final int FILEOP_MOVE_INTRA_PROVIDER = 7; // Move within a provider.
+    static final int FILEOP_MOVE_SYSTEM_PROVIDER = 8; // Move to a system provider.
+    static final int FILEOP_MOVE_EXTERNAL_PROVIDER = 9; // Move to a 3rd-party provider.
+    static final int FILEOP_DELETE = 10;
+    static final int FILEOP_RENAME = 11;
+    static final int FILEOP_CREATE_DIR = 12;
+    static final int FILEOP_OTHER_ERROR = 13;
+    static final int FILEOP_DELETE_ERROR = 14;
+    static final int FILEOP_MOVE_ERROR = 15;
+    static final int FILEOP_COPY_ERROR = 16;
+    static final int FILEOP_RENAME_ERROR = 17;
+    static final int FILEOP_CREATE_DIR_ERROR = 18;
+    static final int FILEOP_COMPRESS_INTRA_PROVIDER = 19; // Compres within a provider
+    static final int FILEOP_COMPRESS_SYSTEM_PROVIDER = 20; // Compress to a system provider.
+    static final int FILEOP_COMPRESS_EXTERNAL_PROVIDER = 21; // Compress to a 3rd-party provider.
+    static final int FILEOP_EXTRACT_INTRA_PROVIDER = 22; // Extract within a provider
+    static final int FILEOP_EXTRACT_SYSTEM_PROVIDER = 23; // Extract to a system provider.
+    static final int FILEOP_EXTRACT_EXTERNAL_PROVIDER = 24; // Extract to a 3rd-party provider.
+    static final int FILEOP_COMPRESS_ERROR = 25;
+    static final int FILEOP_EXTRACT_ERROR = 26;
+
+    @IntDef(flag = true, value = {
+            FILEOP_UNKNOWN,
+            FILEOP_OTHER,
+            FILEOP_COPY,
+            FILEOP_COPY_INTRA_PROVIDER,
+            FILEOP_COPY_SYSTEM_PROVIDER,
+            FILEOP_COPY_EXTERNAL_PROVIDER,
+            FILEOP_MOVE,
+            FILEOP_MOVE_INTRA_PROVIDER,
+            FILEOP_MOVE_SYSTEM_PROVIDER,
+            FILEOP_MOVE_EXTERNAL_PROVIDER,
+            FILEOP_DELETE,
+            FILEOP_RENAME,
+            FILEOP_CREATE_DIR,
+            FILEOP_OTHER_ERROR,
+            FILEOP_DELETE_ERROR,
+            FILEOP_MOVE_ERROR,
+            FILEOP_COPY_ERROR,
+            FILEOP_RENAME_ERROR,
+            FILEOP_CREATE_DIR_ERROR,
+            FILEOP_COMPRESS_INTRA_PROVIDER,
+            FILEOP_COMPRESS_SYSTEM_PROVIDER,
+            FILEOP_COMPRESS_EXTERNAL_PROVIDER,
+            FILEOP_EXTRACT_INTRA_PROVIDER,
+            FILEOP_EXTRACT_SYSTEM_PROVIDER,
+            FILEOP_EXTRACT_EXTERNAL_PROVIDER,
+            FILEOP_COMPRESS_ERROR,
+            FILEOP_EXTRACT_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FileOp {
+    }
+
+    // Codes representing different provider types.  Used for sorting file operations when logging.
+    static final int PROVIDER_INTRA = 0;
+    static final int PROVIDER_SYSTEM = 1;
+    static final int PROVIDER_EXTERNAL = 2;
+
+    @IntDef(flag = false, value = {
+            PROVIDER_INTRA,
+            PROVIDER_SYSTEM,
+            PROVIDER_EXTERNAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Provider {
+    }
+
+    // Codes representing different types of sub-fileops.
+    public static final int SUBFILEOP_UNKNOWN = 0;
+    public static final int SUBFILEOP_QUERY_DOCUMENT = 1;
+    public static final int SUBFILEOP_QUERY_CHILDREN = 2;
+    public static final int SUBFILEOP_OPEN_FILE = 3;
+    public static final int SUBFILEOP_READ_FILE = 4;
+    public static final int SUBFILEOP_CREATE_DOCUMENT = 5;
+    public static final int SUBFILEOP_WRITE_FILE = 6;
+    public static final int SUBFILEOP_DELETE_DOCUMENT = 7;
+    public static final int SUBFILEOP_OBTAIN_STREAM_TYPE = 8;
+    public static final int SUBFILEOP_QUICK_MOVE = 9;
+    public static final int SUBFILEOP_QUICK_COPY = 10;
+
+    @IntDef(flag = false, value = {
+            SUBFILEOP_UNKNOWN,
+            SUBFILEOP_QUERY_DOCUMENT,
+            SUBFILEOP_QUERY_CHILDREN,
+            SUBFILEOP_OPEN_FILE,
+            SUBFILEOP_READ_FILE,
+            SUBFILEOP_CREATE_DOCUMENT,
+            SUBFILEOP_WRITE_FILE,
+            SUBFILEOP_DELETE_DOCUMENT,
+            SUBFILEOP_OBTAIN_STREAM_TYPE,
+            SUBFILEOP_QUICK_MOVE,
+            SUBFILEOP_QUICK_COPY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SubFileOp {
+    }
+
+    // Codes representing different user actions
+    public static final int USER_ACTION_UNKNOWN = 0;
+    public static final int USER_ACTION_OTHER = 1;
+    public static final int USER_ACTION_GRID = 2;
+    public static final int USER_ACTION_LIST = 3;
+    public static final int USER_ACTION_SORT_NAME = 4;
+    public static final int USER_ACTION_SORT_DATE = 5;
+    public static final int USER_ACTION_SORT_SIZE = 6;
+    public static final int USER_ACTION_SORT_TYPE = 7;
+    public static final int USER_ACTION_SEARCH = 8;
+    public static final int USER_ACTION_SHOW_SIZE = 9;
+    public static final int USER_ACTION_HIDE_SIZE = 10;
+    public static final int USER_ACTION_SETTINGS = 11;
+    public static final int USER_ACTION_COPY_TO = 12;
+    public static final int USER_ACTION_MOVE_TO = 13;
+    public static final int USER_ACTION_DELETE = 14;
+    public static final int USER_ACTION_RENAME = 15;
+    public static final int USER_ACTION_CREATE_DIR = 16;
+    public static final int USER_ACTION_SELECT_ALL = 17;
+    public static final int USER_ACTION_SHARE = 18;
+    public static final int USER_ACTION_OPEN = 19;
+    public static final int USER_ACTION_SHOW_ADVANCED = 20;
+    public static final int USER_ACTION_HIDE_ADVANCED = 21;
+    public static final int USER_ACTION_NEW_WINDOW = 22;
+    public static final int USER_ACTION_PASTE_CLIPBOARD = 23;
+    public static final int USER_ACTION_COPY_CLIPBOARD = 24;
+    public static final int USER_ACTION_DRAG_N_DROP = 25;
+    public static final int USER_ACTION_DRAG_N_DROP_MULTI_WINDOW = 26;
+    public static final int USER_ACTION_CUT_CLIPBOARD = 27;
+    public static final int USER_ACTION_COMPRESS = 28;
+    public static final int USER_ACTION_EXTRACT_TO = 29;
+    public static final int USER_ACTION_VIEW_IN_APPLICATION = 30;
+    public static final int USER_ACTION_INSPECTOR = 31;
+    public static final int USER_ACTION_SEARCH_CHIP = 32;
+    public static final int USER_ACTION_SEARCH_HISTORY = 33;
+
+    @IntDef(flag = false, value = {
+            USER_ACTION_UNKNOWN,
+            USER_ACTION_OTHER,
+            USER_ACTION_GRID,
+            USER_ACTION_LIST,
+            USER_ACTION_SORT_NAME,
+            USER_ACTION_SORT_DATE,
+            USER_ACTION_SORT_SIZE,
+            USER_ACTION_SORT_TYPE,
+            USER_ACTION_SEARCH,
+            USER_ACTION_SHOW_SIZE,
+            USER_ACTION_HIDE_SIZE,
+            USER_ACTION_SETTINGS,
+            USER_ACTION_COPY_TO,
+            USER_ACTION_MOVE_TO,
+            USER_ACTION_DELETE,
+            USER_ACTION_RENAME,
+            USER_ACTION_CREATE_DIR,
+            USER_ACTION_SELECT_ALL,
+            USER_ACTION_SHARE,
+            USER_ACTION_OPEN,
+            USER_ACTION_SHOW_ADVANCED,
+            USER_ACTION_HIDE_ADVANCED,
+            USER_ACTION_NEW_WINDOW,
+            USER_ACTION_PASTE_CLIPBOARD,
+            USER_ACTION_COPY_CLIPBOARD,
+            USER_ACTION_DRAG_N_DROP,
+            USER_ACTION_DRAG_N_DROP_MULTI_WINDOW,
+            USER_ACTION_CUT_CLIPBOARD,
+            USER_ACTION_COMPRESS,
+            USER_ACTION_EXTRACT_TO,
+            USER_ACTION_VIEW_IN_APPLICATION,
+            USER_ACTION_INSPECTOR,
+            USER_ACTION_SEARCH_CHIP,
+            USER_ACTION_SEARCH_HISTORY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserAction {
+    }
+
+    // Codes representing different approaches to copy/move a document. OPMODE_PROVIDER indicates
+    // it's an optimized operation provided by providers; OPMODE_CONVERTED means it's converted from
+    // a virtual file; and OPMODE_CONVENTIONAL means it's byte copied.
+    public static final int OPMODE_UNKNOWN = 0;
+    public static final int OPMODE_PROVIDER = 1;
+    public static final int OPMODE_CONVERTED = 2;
+    public static final int OPMODE_CONVENTIONAL = 3;
+
+    @IntDef({OPMODE_UNKNOWN, OPMODE_PROVIDER, OPMODE_CONVERTED, OPMODE_CONVENTIONAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FileOpMode {
+    }
+
+    // Codes representing different menu actions.
+    static final int ACTION_UNKNOWN = 0;
+    static final int ACTION_OPEN = 1;
+    static final int ACTION_CREATE = 2;
+    static final int ACTION_GET_CONTENT = 3;
+    static final int ACTION_OPEN_TREE = 4;
+    static final int ACTION_PICK_COPY_DESTINATION = 5;
+    static final int ACTION_BROWSE = 6;
+    static final int ACTION_OTHER = 7;
+
+    @IntDef(flag = true, value = {
+            ACTION_UNKNOWN,
+            ACTION_OPEN,
+            ACTION_CREATE,
+            ACTION_GET_CONTENT,
+            ACTION_OPEN_TREE,
+            ACTION_PICK_COPY_DESTINATION,
+            ACTION_BROWSE,
+            ACTION_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MetricsAction {
+    }
+
+    public static final int AUTH_UNKNOWN = 0;
+    public static final int AUTH_OTHER = 1;
+    public static final int AUTH_MEDIA = 2;
+    public static final int AUTH_STORAGE_INTERNAL = 3;
+    public static final int AUTH_STORAGE_EXTERNAL = 4;
+    public static final int AUTH_DOWNLOADS = 5;
+    public static final int AUTH_MTP = 6;
+
+    @IntDef(flag = true, value = {
+            AUTH_UNKNOWN,
+            AUTH_OTHER,
+            AUTH_MEDIA,
+            AUTH_STORAGE_INTERNAL,
+            AUTH_STORAGE_EXTERNAL,
+            AUTH_DOWNLOADS,
+            AUTH_MTP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MetricsAuth {
+    }
+
+    // Types for logInvalidScopedAccessRequest
+    public static final int SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS = 1;
+    public static final int SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY = 2;
+    public static final int SCOPED_DIRECTORY_ACCESS_ERROR = 3;
+    public static final int SCOPED_DIRECTORY_ACCESS_DEPRECATED = 4;
+
+    @IntDef(value = {
+            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
+            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
+            SCOPED_DIRECTORY_ACCESS_ERROR,
+            SCOPED_DIRECTORY_ACCESS_DEPRECATED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InvalidScopedAccess {
+    }
+
+    // Codes representing different search types
+    public static final int TYPE_UNKNOWN = 0;
+    public static final int TYPE_CHIP_IMAGES = 1;
+    public static final int TYPE_CHIP_AUDIOS = 2;
+    public static final int TYPE_CHIP_VIDEOS = 3;
+    public static final int TYPE_CHIP_DOCS = 4;
+    public static final int TYPE_SEARCH_HISTORY = 5;
+    public static final int TYPE_SEARCH_STRING = 6;
+
+    @IntDef(flag = true, value = {
+            TYPE_UNKNOWN,
+            TYPE_CHIP_IMAGES,
+            TYPE_CHIP_AUDIOS,
+            TYPE_CHIP_VIDEOS,
+            TYPE_CHIP_DOCS,
+            TYPE_SEARCH_HISTORY,
+            TYPE_SEARCH_STRING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SearchType {}
+
+    // Codes representing different search types
+    public static final int SEARCH_UNKNOWN = 0;
+    public static final int SEARCH_KEYWORD = 1;
+    public static final int SEARCH_CHIPS = 2;
+    public static final int SEARCH_KEYWORD_N_CHIPS = 3;
+
+    @IntDef(flag = true, value = {
+            SEARCH_UNKNOWN,
+            SEARCH_KEYWORD,
+            SEARCH_CHIPS,
+            SEARCH_KEYWORD_N_CHIPS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SearchMode {}
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/Metrics.java b/src/com/android/documentsui/Metrics.java
index fba24be..125a9fa 100644
--- a/src/com/android/documentsui/Metrics.java
+++ b/src/com/android/documentsui/Metrics.java
@@ -16,11 +16,10 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
+import static android.content.ContentResolver.wrap;
 
-import android.annotation.IntDef;
-import android.annotation.Nullable;
+import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
+
 import android.content.ContentProviderClient;
 import android.content.Context;
 import android.content.Intent;
@@ -32,19 +31,19 @@
 import android.provider.DocumentsProvider;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
-import com.android.documentsui.base.State.ActionType;
 import com.android.documentsui.files.LauncherActivity;
+import com.android.documentsui.picker.PickResult;
 import com.android.documentsui.roots.ProvidersAccess;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
-import com.android.internal.logging.MetricsLogger;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import java.io.FileNotFoundException;
 import java.util.List;
 
 /**
@@ -53,445 +52,52 @@
 public final class Metrics {
     private static final String TAG = "Metrics";
 
-    // These strings have to be whitelisted in tron. Do not change them.
-    private static final String COUNT_LAUNCH_ACTION = "docsui_launch_action";
-    private static final String COUNT_ROOT_VISITED_IN_MANAGER
-            = "docsui_root_visited_in_manager";
-    private static final String COUNT_ROOT_VISITED_IN_PICKER
-            = "docsui_root_visited_in_picker";
-    private static final String COUNT_OPEN_MIME = "docsui_open_mime";
-    private static final String COUNT_CREATE_MIME = "docsui_create_mime";
-    private static final String COUNT_GET_CONTENT_MIME = "docsui_get_content_mime";
-    private static final String COUNT_BROWSE_ROOT = "docsui_browse_root";
-    @Deprecated private static final String COUNT_MANAGE_ROOT = "docsui_manage_root";
-    @Deprecated private static final String COUNT_MULTI_WINDOW = "docsui_multi_window";
-    private static final String COUNT_FILEOP_SYSTEM = "docsui_fileop_system";
-    private static final String COUNT_FILEOP_EXTERNAL = "docsui_fileop_external";
-    private static final String COUNT_FILEOP_CANCELED = "docsui_fileop_canceled";
-    private static final String COUNT_STARTUP_MS = "docsui_startup_ms";
-    @Deprecated private static final String COUNT_DRAWER_OPENED = "docsui_drawer_opened";
-    private static final String COUNT_USER_ACTION = "docsui_menu_action";
-    private static final String COUNT_BROWSE_AT_LOCATION = "docsui_browse_at_location";
-    private static final String COUNT_CREATE_AT_LOCATION = "docsui_create_at_location";
-    private static final String COUNT_OPEN_AT_LOCATION = "docsui_open_at_location";
-    private static final String COUNT_GET_CONTENT_AT_LOCATION = "docsui_get_content_at_location";
-    private static final String COUNT_MEDIA_FILEOP_FAILURE = "docsui_media_fileop_failure";
-    private static final String COUNT_DOWNLOADS_FILEOP_FAILURE = "docsui_downloads_fileop_failure";
-    private static final String COUNT_INTERNAL_STORAGE_FILEOP_FAILURE
-            = "docsui_internal_storage_fileop_failure";
-    private static final String COUNT_EXTERNAL_STORAGE_FILEOP_FAILURE
-            = "docsui_external_storage_fileop_failure";
-    private static final String COUNT_MTP_FILEOP_FAILURE = "docsui_mtp_fileop_failure";
-    private static final String COUNT_OTHER_FILEOP_FAILURE = "docsui_other_fileop_failure";
-    private static final String COUNT_FILE_COPIED = "docsui_file_copied";
-    private static final String COUNT_FILE_MOVED = "docsui_file_moved";
-
-    // Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
-    // root that is not explicitly recognized by the Metrics code (see {@link
-    // #getSanitizedRootIndex}). Apps are also bucketed in this histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the end
-    // of the list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int ROOT_NONE = 1;
-    private static final int ROOT_OTHER = 2;
-    private static final int ROOT_AUDIO = 3;
-    private static final int ROOT_DEVICE_STORAGE = 4;
-    private static final int ROOT_DOWNLOADS = 5;
-    private static final int ROOT_HOME = 6;
-    private static final int ROOT_IMAGES = 7;
-    private static final int ROOT_RECENTS = 8;
-    private static final int ROOT_VIDEOS = 9;
-    private static final int ROOT_MTP = 10;
-    // Apps aren't really "roots", but they are treated as such in the roots fragment UI and so they
-    // are logged analogously to roots.
-    private static final int ROOT_THIRD_PARTY_APP = 100;
-
-    @IntDef(flag = true, value = {
-            ROOT_NONE,
-            ROOT_OTHER,
-            ROOT_AUDIO,
-            ROOT_DEVICE_STORAGE,
-            ROOT_DOWNLOADS,
-            ROOT_HOME,
-            ROOT_IMAGES,
-            ROOT_RECENTS,
-            ROOT_VIDEOS,
-            ROOT_MTP,
-            ROOT_THIRD_PARTY_APP
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Root {}
-
-    // Indices for bucketing mime types.
-    // Do not change or rearrange these values, that will break historical data. Only add to the end
-    // of the list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int MIME_NONE = 1; // null mime
-    private static final int MIME_ANY = 2; // */*
-    private static final int MIME_APPLICATION = 3; // application/*
-    private static final int MIME_AUDIO = 4; // audio/*
-    private static final int MIME_IMAGE = 5; // image/*
-    private static final int MIME_MESSAGE = 6; // message/*
-    private static final int MIME_MULTIPART = 7; // multipart/*
-    private static final int MIME_TEXT = 8; // text/*
-    private static final int MIME_VIDEO = 9; // video/*
-    private static final int MIME_OTHER = 10; // anything not enumerated below
-
-    @IntDef(flag = true, value = {
-            MIME_NONE,
-            MIME_ANY,
-            MIME_APPLICATION,
-            MIME_AUDIO,
-            MIME_IMAGE,
-            MIME_MESSAGE,
-            MIME_MULTIPART,
-            MIME_TEXT,
-            MIME_VIDEO,
-            MIME_OTHER
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Mime {}
-
-    public static final int FILES_SCOPE = 1;
-    public static final int PICKER_SCOPE = 2;
-
-    @IntDef({ FILES_SCOPE, PICKER_SCOPE })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ContextScope {}
-
-    // Codes representing different kinds of file operations. These are used for bucketing
-    // operations in the COUNT_FILEOP_{SYSTEM|EXTERNAL} histograms.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int FILEOP_OTHER = 1; // any file operation not listed below
-    private static final int FILEOP_COPY_INTRA_PROVIDER = 2; // Copy within a provider
-    private static final int FILEOP_COPY_SYSTEM_PROVIDER = 3; // Copy to a system provider.
-    private static final int FILEOP_COPY_EXTERNAL_PROVIDER = 4; // Copy to a 3rd-party provider.
-    private static final int FILEOP_MOVE_INTRA_PROVIDER = 5; // Move within a provider.
-    private static final int FILEOP_MOVE_SYSTEM_PROVIDER = 6; // Move to a system provider.
-    private static final int FILEOP_MOVE_EXTERNAL_PROVIDER = 7; // Move to a 3rd-party provider.
-    private static final int FILEOP_DELETE = 8;
-    private static final int FILEOP_RENAME = 9;
-    private static final int FILEOP_CREATE_DIR = 10;
-    private static final int FILEOP_OTHER_ERROR = 100;
-    private static final int FILEOP_DELETE_ERROR = 101;
-    private static final int FILEOP_MOVE_ERROR = 102;
-    private static final int FILEOP_COPY_ERROR = 103;
-    private static final int FILEOP_RENAME_ERROR = 104;
-    private static final int FILEOP_CREATE_DIR_ERROR = 105;
-    private static final int FILEOP_COMPRESS_INTRA_PROVIDER = 106; // Compres within a provider
-    private static final int FILEOP_COMPRESS_SYSTEM_PROVIDER = 107; // Compress to a system provider.
-    private static final int FILEOP_COMPRESS_EXTERNAL_PROVIDER = 108; // Compress to a 3rd-party provider.
-    private static final int FILEOP_EXTRACT_INTRA_PROVIDER = 109; // Extract within a provider
-    private static final int FILEOP_EXTRACT_SYSTEM_PROVIDER = 110; // Extract to a system provider.
-    private static final int FILEOP_EXTRACT_EXTERNAL_PROVIDER = 111; // Extract to a 3rd-party provider.
-    private static final int FILEOP_COMPRESS_ERROR = 112;
-    private static final int FILEOP_EXTRACT_ERROR = 113;
-
-    @IntDef(flag = true, value = {
-            FILEOP_OTHER,
-            FILEOP_COPY_INTRA_PROVIDER,
-            FILEOP_COPY_SYSTEM_PROVIDER,
-            FILEOP_COPY_EXTERNAL_PROVIDER,
-            FILEOP_MOVE_INTRA_PROVIDER,
-            FILEOP_MOVE_SYSTEM_PROVIDER,
-            FILEOP_MOVE_EXTERNAL_PROVIDER,
-            FILEOP_DELETE,
-            FILEOP_RENAME,
-            FILEOP_CREATE_DIR,
-            FILEOP_OTHER_ERROR,
-            FILEOP_DELETE_ERROR,
-            FILEOP_MOVE_ERROR,
-            FILEOP_COPY_ERROR,
-            FILEOP_RENAME_ERROR,
-            FILEOP_CREATE_DIR_ERROR,
-            FILEOP_COMPRESS_INTRA_PROVIDER,
-            FILEOP_COMPRESS_SYSTEM_PROVIDER,
-            FILEOP_COMPRESS_EXTERNAL_PROVIDER,
-            FILEOP_EXTRACT_INTRA_PROVIDER,
-            FILEOP_EXTRACT_SYSTEM_PROVIDER,
-            FILEOP_EXTRACT_EXTERNAL_PROVIDER,
-            FILEOP_COMPRESS_ERROR,
-            FILEOP_EXTRACT_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FileOp {}
-
-    // Codes representing different kinds of file operations. These are used for bucketing
-    // operations in the COUNT_FILEOP_CANCELED histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int OPERATION_UNKNOWN = 1;
-    private static final int OPERATION_COPY = 2;
-    private static final int OPERATION_MOVE = 3;
-    private static final int OPERATION_DELETE = 4;
-    private static final int OPERATION_COMPRESS = 5;
-    private static final int OPERATION_EXTRACT = 6;
-
-    @IntDef(flag = true, value = {
-            OPERATION_UNKNOWN,
-            OPERATION_COPY,
-            OPERATION_MOVE,
-            OPERATION_DELETE,
-            OPERATION_COMPRESS,
-            OPERATION_EXTRACT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MetricsOpType {}
-
-    // Codes representing different provider types.  Used for sorting file operations when logging.
-    private static final int PROVIDER_INTRA = 0;
-    private static final int PROVIDER_SYSTEM = 1;
-    private static final int PROVIDER_EXTERNAL = 2;
-
-    @IntDef(flag = false, value = {
-            PROVIDER_INTRA,
-            PROVIDER_SYSTEM,
-            PROVIDER_EXTERNAL
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Provider {}
-
-    // Codes representing different types of sub-fileops. These are used for bucketing fileop
-    // failures in COUNT_*_FILEOP_FAILURE.
-    public static final int SUBFILEOP_QUERY_DOCUMENT = 1;
-    public static final int SUBFILEOP_QUERY_CHILDREN = 2;
-    public static final int SUBFILEOP_OPEN_FILE = 3;
-    public static final int SUBFILEOP_READ_FILE = 4;
-    public static final int SUBFILEOP_CREATE_DOCUMENT = 5;
-    public static final int SUBFILEOP_WRITE_FILE = 6;
-    public static final int SUBFILEOP_DELETE_DOCUMENT = 7;
-    public static final int SUBFILEOP_OBTAIN_STREAM_TYPE = 8;
-    public static final int SUBFILEOP_QUICK_MOVE = 9;
-    public static final int SUBFILEOP_QUICK_COPY = 10;
-
-    @IntDef(flag = false, value = {
-            SUBFILEOP_QUERY_DOCUMENT,
-            SUBFILEOP_QUERY_CHILDREN,
-            SUBFILEOP_OPEN_FILE,
-            SUBFILEOP_READ_FILE,
-            SUBFILEOP_CREATE_DOCUMENT,
-            SUBFILEOP_WRITE_FILE,
-            SUBFILEOP_DELETE_DOCUMENT,
-            SUBFILEOP_OBTAIN_STREAM_TYPE,
-            SUBFILEOP_QUICK_MOVE,
-            SUBFILEOP_QUICK_COPY
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SubFileOp {}
-
-    // Codes representing different user actions. These are used for bucketing stats in the
-    // COUNT_USER_ACTION histogram.
-    // The historgram includes action triggered from menu or invoked by keyboard shortcut.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    public static final int USER_ACTION_OTHER = 1;
-    public static final int USER_ACTION_GRID = 2;
-    public static final int USER_ACTION_LIST = 3;
-    public static final int USER_ACTION_SORT_NAME = 4;
-    public static final int USER_ACTION_SORT_DATE = 5;
-    public static final int USER_ACTION_SORT_SIZE = 6;
-    public static final int USER_ACTION_SEARCH = 7;
-    public static final int USER_ACTION_SHOW_SIZE = 8;
-    public static final int USER_ACTION_HIDE_SIZE = 9;
-    public static final int USER_ACTION_SETTINGS = 10;
-    public static final int USER_ACTION_COPY_TO = 11;
-    public static final int USER_ACTION_MOVE_TO = 12;
-    public static final int USER_ACTION_DELETE = 13;
-    public static final int USER_ACTION_RENAME = 14;
-    public static final int USER_ACTION_CREATE_DIR = 15;
-    public static final int USER_ACTION_SELECT_ALL = 16;
-    public static final int USER_ACTION_SHARE = 17;
-    public static final int USER_ACTION_OPEN = 18;
-    public static final int USER_ACTION_SHOW_ADVANCED = 19;
-    public static final int USER_ACTION_HIDE_ADVANCED = 20;
-    public static final int USER_ACTION_NEW_WINDOW = 21;
-    public static final int USER_ACTION_PASTE_CLIPBOARD = 22;
-    public static final int USER_ACTION_COPY_CLIPBOARD = 23;
-    public static final int USER_ACTION_DRAG_N_DROP = 24;
-    public static final int USER_ACTION_DRAG_N_DROP_MULTI_WINDOW = 25;
-    public static final int USER_ACTION_CUT_CLIPBOARD = 26;
-    public static final int USER_ACTION_COMPRESS = 27;
-    public static final int USER_ACTION_EXTRACT_TO = 28;
-    public static final int USER_ACTION_VIEW_IN_APPLICATION = 29;
-    public static final int USER_ACTION_INSPECTOR = 30;
-
-    @IntDef(flag = false, value = {
-            USER_ACTION_OTHER,
-            USER_ACTION_GRID,
-            USER_ACTION_LIST,
-            USER_ACTION_SORT_NAME,
-            USER_ACTION_SORT_DATE,
-            USER_ACTION_SORT_SIZE,
-            USER_ACTION_SEARCH,
-            USER_ACTION_SHOW_SIZE,
-            USER_ACTION_HIDE_SIZE,
-            USER_ACTION_SETTINGS,
-            USER_ACTION_COPY_TO,
-            USER_ACTION_MOVE_TO,
-            USER_ACTION_DELETE,
-            USER_ACTION_RENAME,
-            USER_ACTION_CREATE_DIR,
-            USER_ACTION_SELECT_ALL,
-            USER_ACTION_SHARE,
-            USER_ACTION_OPEN,
-            USER_ACTION_SHOW_ADVANCED,
-            USER_ACTION_HIDE_ADVANCED,
-            USER_ACTION_NEW_WINDOW,
-            USER_ACTION_PASTE_CLIPBOARD,
-            USER_ACTION_COPY_CLIPBOARD,
-            USER_ACTION_DRAG_N_DROP,
-            USER_ACTION_DRAG_N_DROP_MULTI_WINDOW,
-            USER_ACTION_CUT_CLIPBOARD,
-            USER_ACTION_COMPRESS,
-            USER_ACTION_EXTRACT_TO,
-            USER_ACTION_VIEW_IN_APPLICATION,
-            USER_ACTION_INSPECTOR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface UserAction {}
-
-    // Codes representing different approaches to copy/move a document. OPMODE_PROVIDER indicates
-    // it's an optimized operation provided by providers; OPMODE_CONVERTED means it's converted from
-    // a virtual file; and OPMODE_CONVENTIONAL means it's byte copied.
-    public static final int OPMODE_PROVIDER = 1;
-    public static final int OPMODE_CONVERTED = 2;
-    public static final int OPMODE_CONVENTIONAL = 3;
-    @IntDef({OPMODE_PROVIDER, OPMODE_CONVERTED, OPMODE_CONVENTIONAL})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FileOpMode {}
-
-    // Codes representing different menu actions. These are used for bucketing stats in the
-    // COUNT_MENU_ACTION histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int ACTION_OTHER = 1;
-    private static final int ACTION_OPEN = 2;
-    private static final int ACTION_CREATE = 3;
-    private static final int ACTION_GET_CONTENT = 4;
-    private static final int ACTION_OPEN_TREE = 5;
-    @Deprecated private static final int ACTION_MANAGE = 6;
-    private static final int ACTION_BROWSE = 7;
-    private static final int ACTION_PICK_COPY_DESTINATION = 8;
-
-    @IntDef(flag = true, value = {
-            ACTION_OTHER,
-            ACTION_OPEN,
-            ACTION_CREATE,
-            ACTION_GET_CONTENT,
-            ACTION_OPEN_TREE,
-            ACTION_MANAGE,
-            ACTION_BROWSE,
-            ACTION_PICK_COPY_DESTINATION
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MetricsAction {}
-
-    // Codes representing different actions to open the drawer. They are used for bucketing stats in
-    // the COUNT_DRAWER_OPENED histogram.
-    // Do not change or rearrange these values, that will break historical data. Only add to the
-    // list.
-    // Do not use negative numbers or zero; clearcut only handles positive integers.
-    private static final int DRAWER_OPENED_HAMBURGER = 1;
-    private static final int DRAWER_OPENED_SWIPE = 2;
-
-    @IntDef(flag = true, value = {
-            DRAWER_OPENED_HAMBURGER,
-            DRAWER_OPENED_SWIPE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DrawerTrigger {}
-
     /**
      * Logs when DocumentsUI is started, and how. Call this when DocumentsUI first starts up.
      *
-     * @param context
      * @param state
      * @param intent
      */
-    public static void logActivityLaunch(Context context, State state, Intent intent) {
-        // Log the launch action.
-        logHistogram(context, COUNT_LAUNCH_ACTION, toMetricsAction(state.action));
-        // Then log auxiliary data (roots/mime types) associated with some actions.
+    public static void logActivityLaunch(State state, Intent intent) {
         Uri uri = intent.getData();
-        switch (state.action) {
-            case State.ACTION_OPEN:
-                logHistogram(context, COUNT_OPEN_MIME, sanitizeMime(intent.getType()));
-                break;
-            case State.ACTION_CREATE:
-                logHistogram(context, COUNT_CREATE_MIME, sanitizeMime(intent.getType()));
-                break;
-            case State.ACTION_GET_CONTENT:
-                logHistogram(context, COUNT_GET_CONTENT_MIME, sanitizeMime(intent.getType()));
-                break;
-            case State.ACTION_BROWSE:
-                logHistogram(context, COUNT_BROWSE_ROOT, sanitizeRoot(uri));
-                break;
-            default:
-                break;
-        }
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_LAUNCH_REPORTED,
+                toMetricsAction(state.action), false,
+                sanitizeMime(intent.getType()), sanitizeRoot(uri));
     }
 
     /**
      * Logs when DocumentsUI are launched with {@link DocumentsContract#EXTRA_INITIAL_URI}.
      *
-     * @param context
      * @param state used to resolve action
      * @param rootUri the resolved rootUri, or {@code null} if the provider doesn't
      *                support {@link DocumentsProvider#findDocumentPath(String, String)}
      */
-    public static void logLaunchAtLocation(Context context, State state, @Nullable Uri rootUri) {
-        switch (state.action) {
-            case State.ACTION_BROWSE:
-                logHistogram(context, COUNT_BROWSE_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-            case State.ACTION_CREATE:
-                logHistogram(context, COUNT_CREATE_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-            case State.ACTION_GET_CONTENT:
-                logHistogram(context, COUNT_GET_CONTENT_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-            case State.ACTION_OPEN:
-                logHistogram(context, COUNT_OPEN_AT_LOCATION, sanitizeRoot(rootUri));
-                break;
-        }
+    public static void logLaunchAtLocation(State state, @Nullable Uri rootUri) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_LAUNCH_REPORTED,
+                toMetricsAction(state.action), true,
+                MetricConsts.MIME_UNKNOWN, sanitizeRoot(rootUri));
     }
 
     /**
      * Logs a root visited event in file managers. Call this when the user
      * taps on a root in {@link com.android.documentsui.sidebar.RootsFragment}.
-     *
-     * @param context
      * @param scope
      * @param info
      */
-    public static void logRootVisited(
-            Context context, @ContextScope int scope, RootInfo info) {
-        switch (scope) {
-            case FILES_SCOPE:
-                logHistogram(context, COUNT_ROOT_VISITED_IN_MANAGER,
-                        sanitizeRoot(info));
-                break;
-            case PICKER_SCOPE:
-                logHistogram(context, COUNT_ROOT_VISITED_IN_PICKER,
-                        sanitizeRoot(info));
-                break;
-        }
+    public static void logRootVisited(@MetricConsts.ContextScope int scope, RootInfo info) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_ROOT_VISITED, scope, sanitizeRoot(info));
     }
 
     /**
      * Logs an app visited event in file pickers. Call this when the user visits
      * on an app in the RootsFragment.
      *
-     * @param context
      * @param info
      */
-    public static void logAppVisited(Context context, ResolveInfo info) {
-        logHistogram(context, COUNT_ROOT_VISITED_IN_PICKER, sanitizeRoot(info));
+    public static void logAppVisited(ResolveInfo info) {
+        DocumentsStatsLog.write(
+                DocumentsStatsLog.DOCS_UI_ROOT_VISITED,
+                MetricConsts.PICKER_SCOPE, sanitizeRoot(info));
     }
 
     /**
@@ -499,41 +105,39 @@
      * DocumentInfo is only used to distinguish broad categories of actions (e.g. copying from one
      * provider to another vs copying within a given provider).  No PII is logged.
      *
-     * @param context
      * @param operationType
      * @param srcs
      * @param dst
      */
     public static void logFileOperation(
-            Context context,
             @OpType int operationType,
             List<DocumentInfo> srcs,
             @Nullable DocumentInfo dst) {
-
         ProviderCounts counts = new ProviderCounts();
         countProviders(counts, srcs, dst);
-
         if (counts.intraProvider > 0) {
-            logIntraProviderFileOps(context, dst.authority, operationType);
+            logIntraProviderFileOps(dst.authority, operationType);
         }
         if (counts.systemProvider > 0) {
             // Log file operations on system providers.
-            logInterProviderFileOps(context, COUNT_FILEOP_SYSTEM, dst, operationType);
+            logInterProviderFileOps(MetricConsts.PROVIDER_SYSTEM, dst, operationType);
         }
         if (counts.externalProvider > 0) {
             // Log file operations on external providers.
-            logInterProviderFileOps(context, COUNT_FILEOP_EXTERNAL, dst, operationType);
+            logInterProviderFileOps(MetricConsts.PROVIDER_EXTERNAL, dst, operationType);
         }
     }
 
     public static void logFileOperated(
-            Context context, @OpType int operationType, @FileOpMode int approach) {
+            @OpType int operationType, @MetricConsts.FileOpMode int approach) {
         switch (operationType) {
             case FileOperationService.OPERATION_COPY:
-                logHistogram(context, COUNT_FILE_COPIED, approach);
+                DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED,
+                        MetricConsts.FILEOP_COPY, approach);
                 break;
             case FileOperationService.OPERATION_MOVE:
-                logHistogram(context, COUNT_FILE_MOVED, approach);
+                DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED,
+                        MetricConsts.FILEOP_MOVE, approach);
                 break;
         }
     }
@@ -542,85 +146,91 @@
      * Logs create directory operation. It is a part of file operation stats. We do not
      * differentiate between internal and external locations, all create directory operations are
      * logged under COUNT_FILEOP_SYSTEM. Call this when a create directory operation has completed.
-     *
-     * @param context
      */
-    public static void logCreateDirOperation(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_CREATE_DIR);
+    public static void logCreateDirOperation() {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_CREATE_DIR);
     }
 
     /**
      * Logs rename file operation. It is a part of file operation stats. We do not differentiate
      * between internal and external locations, all rename operations are logged under
      * COUNT_FILEOP_SYSTEM. Call this when a rename file operation has completed.
-     *
-     * @param context
      */
-    public static void logRenameFileOperation(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_RENAME);
+    public static void logRenameFileOperation() {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_RENAME);
     }
 
     /**
      * Logs some kind of file operation error. Call this when a file operation (e.g. copy, delete)
      * fails.
      *
-     * @param context
      * @param operationType
      * @param failedFiles
      */
-    public static void logFileOperationErrors(Context context, @OpType int operationType,
+    public static void logFileOperationErrors(@OpType int operationType,
             List<DocumentInfo> failedFiles, List<Uri> failedUris) {
-
         ProviderCounts counts = new ProviderCounts();
         countProviders(counts, failedFiles, null);
-
         // TODO: Report URI errors separate from file operation errors.
         countProviders(counts, failedUris);
-
-        @FileOp int opCode = FILEOP_OTHER_ERROR;
+        @MetricConsts.FileOp int opCode = MetricConsts.FILEOP_OTHER_ERROR;
         switch (operationType) {
             case FileOperationService.OPERATION_COPY:
-                opCode = FILEOP_COPY_ERROR;
+                opCode = MetricConsts.FILEOP_COPY_ERROR;
                 break;
             case FileOperationService.OPERATION_COMPRESS:
-                opCode = FILEOP_COMPRESS_ERROR;
+                opCode = MetricConsts.FILEOP_COMPRESS_ERROR;
                 break;
             case FileOperationService.OPERATION_EXTRACT:
-                opCode = FILEOP_EXTRACT_ERROR;
+                opCode = MetricConsts.FILEOP_EXTRACT_ERROR;
                 break;
             case FileOperationService.OPERATION_DELETE:
-                opCode = FILEOP_DELETE_ERROR;
+                opCode = MetricConsts.FILEOP_DELETE_ERROR;
                 break;
             case FileOperationService.OPERATION_MOVE:
-                opCode = FILEOP_MOVE_ERROR;
+                opCode = MetricConsts.FILEOP_MOVE_ERROR;
                 break;
         }
         if (counts.systemProvider > 0) {
-            logHistogram(context, COUNT_FILEOP_SYSTEM, opCode);
+            DocumentsStatsLog.write(
+                    DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                    MetricConsts.PROVIDER_SYSTEM, opCode);
         }
         if (counts.externalProvider > 0) {
-            logHistogram(context, COUNT_FILEOP_EXTERNAL, opCode);
+            DocumentsStatsLog.write(
+                    DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                    MetricConsts.PROVIDER_EXTERNAL, opCode);
         }
     }
 
     public static void logFileOperationFailure(
-            Context context, @SubFileOp int subFileOp, Uri docUri) {
+            Context context, @MetricConsts.SubFileOp int subFileOp, Uri docUri) {
         final String authority = docUri.getAuthority();
         switch (authority) {
             case Providers.AUTHORITY_MEDIA:
-                logHistogram(context, COUNT_MEDIA_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.write(
+                        DocumentsStatsLog.DOCS_UI_FILE_OP_FAILURE,
+                        MetricConsts.AUTH_MEDIA, subFileOp);
                 break;
             case Providers.AUTHORITY_STORAGE:
                 logStorageFileOperationFailure(context, subFileOp, docUri);
                 break;
             case Providers.AUTHORITY_DOWNLOADS:
-                logHistogram(context, COUNT_DOWNLOADS_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.write(
+                        DocumentsStatsLog.DOCS_UI_FILE_OP_FAILURE,
+                        MetricConsts.AUTH_DOWNLOADS, subFileOp);
                 break;
             case Providers.AUTHORITY_MTP:
-                logHistogram(context, COUNT_MTP_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.write(
+                        DocumentsStatsLog.DOCS_UI_FILE_OP_FAILURE,
+                        MetricConsts.AUTH_MTP, subFileOp);
                 break;
             default:
-                logHistogram(context, COUNT_OTHER_FILEOP_FAILURE, subFileOp);
+                DocumentsStatsLog.write(
+                        DocumentsStatsLog.DOCS_UI_FILE_OP_FAILURE,
+                        MetricConsts.AUTH_OTHER, subFileOp);
                 break;
         }
     }
@@ -629,119 +239,118 @@
      * Logs create directory operation error. We do not differentiate between internal and external
      * locations, all create directory errors are logged under COUNT_FILEOP_SYSTEM. Call this when a
      * create directory operation fails.
-     *
-     * @param context
      */
-    public static void logCreateDirError(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_CREATE_DIR_ERROR);
+    public static void logCreateDirError() {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_CREATE_DIR_ERROR);
     }
 
     /**
      * Logs rename file operation error. We do not differentiate between internal and external
      * locations, all rename errors are logged under COUNT_FILEOP_SYSTEM. Call this
      * when a rename file operation fails.
-     *
-     * @param context
      */
-    public static void logRenameFileError(Context context) {
-        logHistogram(context, COUNT_FILEOP_SYSTEM, FILEOP_RENAME_ERROR);
+    public static void logRenameFileError() {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                MetricConsts.PROVIDER_SYSTEM, MetricConsts.FILEOP_RENAME_ERROR);
     }
 
     /**
      * Logs the cancellation of a file operation.  Call this when a Job is canceled.
-     * @param context
+     *
      * @param operationType
      */
-    public static void logFileOperationCancelled(Context context, @OpType int operationType) {
-        logHistogram(context, COUNT_FILEOP_CANCELED, toMetricsOpType(operationType));
+    public static void logFileOperationCancelled(@OpType int operationType) {
+        DocumentsStatsLog.write(
+                DocumentsStatsLog.DOCS_UI_FILE_OP_CANCELED, toMetricsOpType(operationType));
     }
 
     /**
      * Logs startup time in milliseconds.
-     * @param context
+     *
      * @param startupMs Startup time in milliseconds.
      */
-    public static void logStartupMs(Context context, int startupMs) {
-        logHistogram(context, COUNT_STARTUP_MS, startupMs);
+    public static void logStartupMs(int startupMs) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_STARTUP_MS, startupMs);
     }
 
     private static void logInterProviderFileOps(
-            Context context,
-            String histogram,
+            @MetricConsts.Provider int providerType,
             DocumentInfo dst,
             @OpType int operationType) {
         if (operationType == FileOperationService.OPERATION_DELETE) {
-            logHistogram(context, histogram, FILEOP_DELETE);
+            DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                    providerType, MetricConsts.FILEOP_DELETE);
         } else {
             assert(dst != null);
-            @Provider int providerType =
-                    isSystemProvider(dst.authority) ? PROVIDER_SYSTEM : PROVIDER_EXTERNAL;
-            logHistogram(context, histogram, getOpCode(operationType, providerType));
+            @MetricConsts.Provider int opProviderType = isSystemProvider(dst.authority)
+                    ? MetricConsts.PROVIDER_SYSTEM : MetricConsts.PROVIDER_EXTERNAL;
+            DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                    providerType, getOpCode(operationType, opProviderType));
         }
     }
 
-    private static void logIntraProviderFileOps(
-            Context context, String authority, @OpType int operationType) {
-        // Find the right histogram to log to, then log the operation.
-        String histogram = isSystemProvider(authority) ? COUNT_FILEOP_SYSTEM : COUNT_FILEOP_EXTERNAL;
-        logHistogram(context, histogram, getOpCode(operationType, PROVIDER_INTRA));
+    private static void logIntraProviderFileOps(String authority, @OpType int operationType) {
+        @MetricConsts.Provider int providerType = isSystemProvider(authority)
+                ? MetricConsts.PROVIDER_SYSTEM : MetricConsts.PROVIDER_EXTERNAL;
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_PROVIDER_FILE_OP,
+                providerType, getOpCode(operationType, MetricConsts.PROVIDER_INTRA));
     }
 
     /**
      * Logs the action that was started by user.
-     * @param context
+     *
      * @param userAction
      */
-    public static void logUserAction(Context context, @UserAction int userAction) {
-        logHistogram(context, COUNT_USER_ACTION, userAction);
+    public static void logUserAction(@MetricConsts.UserAction int userAction) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_USER_ACTION_REPORTED, userAction);
+    }
+
+    public static void logPickerLaunchedFrom(String packgeName) {
+        DocumentsStatsLog.write(
+                DocumentsStatsLog.DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED, packgeName);
+    }
+
+    public static void logSearchType(int searchType) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_SEARCH_TYPE_REPORTED, searchType);
+    }
+
+    public static void logSearchMode(boolean isKeywordSearch, boolean isChipsSearch) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_SEARCH_MODE_REPORTED,
+                getSearchMode(isKeywordSearch, isChipsSearch));
+    }
+
+    public static void logPickResult(PickResult result) {
+        DocumentsStatsLog.write(
+                DocumentsStatsLog.DOCS_UI_PICK_RESULT_REPORTED,
+                result.getActionCount(),
+                result.getDuration(),
+                result.getFileCount(),
+                result.isSearching(),
+                result.getRoot(),
+                result.getMimeType(),
+                result.getRepeatedPickTimes());
     }
 
     private static void logStorageFileOperationFailure(
-            Context context, @SubFileOp int subFileOp, Uri docUri) {
+            Context context, @MetricConsts.SubFileOp int subFileOp, Uri docUri) {
         assert(Providers.AUTHORITY_STORAGE.equals(docUri.getAuthority()));
-
         boolean isInternal;
         try (ContentProviderClient client = acquireUnstableProviderOrThrow(
                 context.getContentResolver(), Providers.AUTHORITY_STORAGE)) {
-            final Path path = DocumentsContract.findDocumentPath(client, docUri);
-
+            final Path path = DocumentsContract.findDocumentPath(wrap(client), docUri);
             final ProvidersAccess providers = DocumentsApplication.getProvidersCache(context);
             final RootInfo root = providers.getRootOneshot(
                     Providers.AUTHORITY_STORAGE, path.getRootId());
             isInternal = !root.supportsEject();
-        } catch (RemoteException | RuntimeException e) {
+        } catch (FileNotFoundException | RemoteException | RuntimeException e) {
             Log.e(TAG, "Failed to obtain its root info. Log the metrics as internal.", e);
             // It's not very likely to have an external storage so log it as internal.
             isInternal = true;
         }
-
-        final String histogram = isInternal
-                ? COUNT_INTERNAL_STORAGE_FILEOP_FAILURE
-                : COUNT_EXTERNAL_STORAGE_FILEOP_FAILURE;
-        logHistogram(context, histogram, subFileOp);
-    }
-
-    /**
-     * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
-     *
-     * @param context
-     * @param name The counter to increment.
-     */
-    private static void logCount(Context context, String name) {
-        if (DEBUG) Log.d(TAG, name + ": " + 1);
-        MetricsLogger.count(context, name, 1);
-    }
-
-    /**
-     * Internal method for making a MetricsLogger.histogram call.
-     *
-     * @param context
-     * @param name The name of the histogram.
-     * @param bucket The bucket to increment.
-     */
-    private static void logHistogram(Context context, String name, @ActionType int bucket) {
-        if (DEBUG) Log.d(TAG, name + ": " + bucket);
-        MetricsLogger.histogram(context, name, bucket);
+        @MetricConsts.MetricsAuth final int authority = isInternal
+                ? MetricConsts.AUTH_STORAGE_INTERNAL : MetricConsts.AUTH_STORAGE_EXTERNAL;
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_FILE_OP_FAILURE, authority, subFileOp);
     }
 
     /**
@@ -749,53 +358,60 @@
      * small set of hard-coded roots (ones provided by the system). Other roots are all grouped into
      * a single ROOT_OTHER bucket.
      */
-    private static @Root int sanitizeRoot(Uri uri) {
+    private static @MetricConsts.Root int sanitizeRoot(Uri uri) {
         if (uri == null || uri.getAuthority() == null || LauncherActivity.isLaunchUri(uri)) {
-            return ROOT_NONE;
+            return MetricConsts.ROOT_NONE;
         }
-
         switch (uri.getAuthority()) {
             case Providers.AUTHORITY_MEDIA:
-                switch (DocumentsContract.getRootId(uri)) {
+                String rootId = getRootIdSafely(uri);
+                if (rootId == null) {
+                    return MetricConsts.ROOT_NONE;
+                }
+                switch (rootId) {
                     case Providers.ROOT_ID_AUDIO:
-                        return ROOT_AUDIO;
+                        return MetricConsts.ROOT_AUDIO;
                     case Providers.ROOT_ID_IMAGES:
-                        return ROOT_IMAGES;
+                        return MetricConsts.ROOT_IMAGES;
                     case Providers.ROOT_ID_VIDEOS:
-                        return ROOT_VIDEOS;
+                        return MetricConsts.ROOT_VIDEOS;
                     default:
-                        return ROOT_OTHER;
+                        return MetricConsts.ROOT_OTHER_DOCS_PROVIDER;
                 }
             case Providers.AUTHORITY_STORAGE:
-                if (Providers.ROOT_ID_HOME.equals(DocumentsContract.getRootId(uri))) {
-                    return ROOT_HOME;
+                rootId = getRootIdSafely(uri);
+                if (rootId == null) {
+                    return MetricConsts.ROOT_NONE;
+                }
+                if (Providers.ROOT_ID_HOME.equals(rootId)) {
+                    return MetricConsts.ROOT_HOME;
                 } else {
-                    return ROOT_DEVICE_STORAGE;
+                    return MetricConsts.ROOT_DEVICE_STORAGE;
                 }
             case Providers.AUTHORITY_DOWNLOADS:
-                return ROOT_DOWNLOADS;
+                return MetricConsts.ROOT_DOWNLOADS;
             case Providers.AUTHORITY_MTP:
-                return ROOT_MTP;
+                return MetricConsts.ROOT_MTP;
             default:
-                return ROOT_OTHER;
+                return MetricConsts.ROOT_OTHER_DOCS_PROVIDER;
         }
     }
 
     /** @see #sanitizeRoot(Uri) */
-    private static @Root int sanitizeRoot(RootInfo root) {
+    public static @MetricConsts.Root int sanitizeRoot(RootInfo root) {
         if (root.isRecents()) {
             // Recents root is special and only identifiable via this method call. Other roots are
             // identified by URI.
-            return ROOT_RECENTS;
+            return MetricConsts.ROOT_RECENTS;
         } else {
             return sanitizeRoot(root.getUri());
         }
     }
 
     /** @see #sanitizeRoot(Uri) */
-    private static @Root int sanitizeRoot(ResolveInfo info) {
+    public static @MetricConsts.Root int sanitizeRoot(ResolveInfo info) {
         // Log all apps under a single bucket in the roots histogram.
-        return ROOT_THIRD_PARTY_APP;
+        return MetricConsts.ROOT_THIRD_PARTY_APP;
     }
 
     /**
@@ -805,32 +421,32 @@
      * @param mimeType
      * @return
      */
-    private static @Mime int sanitizeMime(String mimeType) {
+    public static @MetricConsts.Mime int sanitizeMime(String mimeType) {
         if (mimeType == null) {
-            return MIME_NONE;
+            return MetricConsts.MIME_NONE;
         } else if ("*/*".equals(mimeType)) {
-            return MIME_ANY;
+            return MetricConsts.MIME_ANY;
         } else {
             String type = mimeType.substring(0, mimeType.indexOf('/'));
             switch (type) {
                 case "application":
-                    return MIME_APPLICATION;
+                    return MetricConsts.MIME_APPLICATION;
                 case "audio":
-                    return MIME_AUDIO;
+                    return MetricConsts.MIME_AUDIO;
                 case "image":
-                    return MIME_IMAGE;
+                    return MetricConsts.MIME_IMAGE;
                 case "message":
-                    return MIME_MESSAGE;
+                    return MetricConsts.MIME_MESSAGE;
                 case "multipart":
-                    return MIME_MULTIPART;
+                    return MetricConsts.MIME_MULTIPART;
                 case "text":
-                    return MIME_TEXT;
+                    return MetricConsts.MIME_TEXT;
                 case "video":
-                    return MIME_VIDEO;
+                    return MetricConsts.MIME_VIDEO;
             }
         }
         // Bucket all other types into one bucket.
-        return MIME_OTHER;
+        return MetricConsts.MIME_OTHER;
     }
 
     private static boolean isSystemProvider(String authority) {
@@ -850,85 +466,98 @@
      * @return An opcode, suitable for use as histogram bucket, for the given operation/provider
      *         combination.
      */
-    private static @FileOp int getOpCode(@OpType int operation, @Provider int providerType) {
+    private static @MetricConsts.FileOp int getOpCode(
+            @OpType int operation, @MetricConsts.Provider int providerType) {
         switch (operation) {
             case FileOperationService.OPERATION_COPY:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_COPY_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_COPY_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_COPY_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_COPY_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_COPY_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_COPY_EXTERNAL_PROVIDER;
                 }
             case FileOperationService.OPERATION_COMPRESS:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_COMPRESS_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_COMPRESS_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_COMPRESS_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_COMPRESS_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_COMPRESS_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_COMPRESS_EXTERNAL_PROVIDER;
                 }
-             case FileOperationService.OPERATION_EXTRACT:
+            case FileOperationService.OPERATION_EXTRACT:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_EXTRACT_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_EXTRACT_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_EXTRACT_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_EXTRACT_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_EXTRACT_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_EXTRACT_EXTERNAL_PROVIDER;
                 }
             case FileOperationService.OPERATION_MOVE:
                 switch (providerType) {
-                    case PROVIDER_INTRA:
-                        return FILEOP_MOVE_INTRA_PROVIDER;
-                    case PROVIDER_SYSTEM:
-                        return FILEOP_MOVE_SYSTEM_PROVIDER;
-                    case PROVIDER_EXTERNAL:
-                        return FILEOP_MOVE_EXTERNAL_PROVIDER;
+                    case MetricConsts.PROVIDER_INTRA:
+                        return MetricConsts.FILEOP_MOVE_INTRA_PROVIDER;
+                    case MetricConsts.PROVIDER_SYSTEM:
+                        return MetricConsts.FILEOP_MOVE_SYSTEM_PROVIDER;
+                    case MetricConsts.PROVIDER_EXTERNAL:
+                        return MetricConsts.FILEOP_MOVE_EXTERNAL_PROVIDER;
                 }
             case FileOperationService.OPERATION_DELETE:
-                return FILEOP_DELETE;
+                return MetricConsts.FILEOP_DELETE;
             default:
                 Log.w(TAG, "Unrecognized operation type when logging a file operation");
-                return FILEOP_OTHER;
+                return MetricConsts.FILEOP_OTHER;
         }
     }
 
     /**
      * Maps FileOperationService OpType values, to MetricsOpType values.
      */
-    private static @MetricsOpType int toMetricsOpType(@OpType int operation) {
+    private static @MetricConsts.FileOp int toMetricsOpType(@OpType int operation) {
         switch (operation) {
             case FileOperationService.OPERATION_COPY:
-                return OPERATION_COPY;
+                return MetricConsts.FILEOP_COPY;
             case FileOperationService.OPERATION_MOVE:
-                return OPERATION_MOVE;
+                return MetricConsts.FILEOP_MOVE;
             case FileOperationService.OPERATION_DELETE:
-                return OPERATION_DELETE;
+                return MetricConsts.FILEOP_DELETE;
             case FileOperationService.OPERATION_UNKNOWN:
             default:
-                return OPERATION_UNKNOWN;
+                return MetricConsts.FILEOP_UNKNOWN;
         }
     }
 
-    private static @MetricsAction int toMetricsAction(int action) {
+    private static @MetricConsts.MetricsAction int toMetricsAction(int action) {
         switch(action) {
             case State.ACTION_OPEN:
-                return ACTION_OPEN;
+                return MetricConsts.ACTION_OPEN;
             case State.ACTION_CREATE:
-                return ACTION_CREATE;
+                return MetricConsts.ACTION_CREATE;
             case State.ACTION_GET_CONTENT:
-                return ACTION_GET_CONTENT;
+                return MetricConsts.ACTION_GET_CONTENT;
             case State.ACTION_OPEN_TREE:
-                return ACTION_OPEN_TREE;
+                return MetricConsts.ACTION_OPEN_TREE;
             case State.ACTION_BROWSE:
-                return ACTION_BROWSE;
+                return MetricConsts.ACTION_BROWSE;
             case State.ACTION_PICK_COPY_DESTINATION:
-                return ACTION_PICK_COPY_DESTINATION;
+                return MetricConsts.ACTION_PICK_COPY_DESTINATION;
             default:
-                return ACTION_OTHER;
+                return MetricConsts.ACTION_OTHER;
+        }
+    }
+
+    private static int getSearchMode(boolean isKeyword, boolean isChip) {
+        if (isKeyword && isChip) {
+            return MetricConsts.SEARCH_KEYWORD_N_CHIPS;
+        } else if (isKeyword) {
+            return MetricConsts.SEARCH_KEYWORD;
+        } else if (isChip) {
+            return MetricConsts.SEARCH_CHIPS;
+        } else {
+            return MetricConsts.SEARCH_UNKNOWN;
         }
     }
 
@@ -971,4 +600,13 @@
         int systemProvider;
         int externalProvider;
     }
+
+    private static String getRootIdSafely(Uri uri) {
+        try {
+            return DocumentsContract.getRootId(uri);
+        } catch (IllegalArgumentException iae) {
+            Log.w(TAG, "Invalid root Uri " + uri.toSafeString());
+        }
+        return null;
+    }
 }
diff --git a/src/com/android/documentsui/Model.java b/src/com/android/documentsui/Model.java
index 16284ea..b9c3d1d 100644
--- a/src/com/android/documentsui/Model.java
+++ b/src/com/android/documentsui/Model.java
@@ -20,25 +20,23 @@
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 import android.app.AuthenticationRequiredException;
 import android.database.Cursor;
-import android.database.MergeCursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 
-import com.android.documentsui.DirectoryResult;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.selection.Selection;
+
 import com.android.documentsui.base.DocumentFilters;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.EventListener;
 import com.android.documentsui.base.Features;
-import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.documentsui.selection.Selection;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -113,10 +111,11 @@
     }
 
     @VisibleForTesting
-    protected void update(DirectoryResult result) {
+    public void update(DirectoryResult result) {
         assert(result != null);
-
-        if (DEBUG) Log.i(TAG, "Updating model with new result set.");
+        if (DEBUG) {
+            Log.i(TAG, "Updating model with new result set.");
+        }
 
         if (result.exception != null) {
             Log.e(TAG, "Error while loading directory contents", result.exception);
@@ -161,14 +160,8 @@
             }
             // Generates a Model ID for a cursor entry that refers to a document. The Model ID is a
             // unique string that can be used to identify the document referred to by the cursor.
-            // If the cursor is a merged cursor over multiple authorities, then prefix the ids
-            // with the authority to avoid collisions.
-            if (mCursor instanceof MergeCursor) {
-                mIds[pos] = getCursorString(mCursor, RootCursorWrapper.COLUMN_AUTHORITY)
-                        + "|" + getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
-            } else {
-                mIds[pos] = getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
-            }
+            // Prefix the ids with the authority to avoid collisions.
+            mIds[pos] = ModelId.build(mCursor);
             mFileNames.add(getCursorString(mCursor, Document.COLUMN_DISPLAY_NAME));
         }
 
@@ -186,13 +179,17 @@
     public @Nullable Cursor getItem(String modelId) {
         Integer pos = mPositions.get(modelId);
         if (pos == null) {
-            if (DEBUG) Log.d(TAG, "Unabled to find cursor position for modelId: " + modelId);
+            if (DEBUG) {
+                Log.d(TAG, "Unabled to find cursor position for modelId: " + modelId);
+            }
             return null;
         }
 
         if (!mCursor.moveToPosition(pos)) {
-            if (DEBUG) Log.d(TAG,
+            if (DEBUG) {
+                Log.d(TAG,
                     "Unabled to move cursor to position " + pos + " for modelId: " + modelId);
+            }
             return null;
         }
 
@@ -203,7 +200,7 @@
         return mIsLoading;
     }
 
-    public List<DocumentInfo> getDocuments(Selection selection) {
+    public List<DocumentInfo> getDocuments(Selection<String> selection) {
         return loadDocuments(selection, DocumentFilters.ANY);
     }
 
@@ -214,7 +211,7 @@
                 : DocumentInfo.fromDirectoryCursor(cursor);
     }
 
-    public List<DocumentInfo> loadDocuments(Selection selection, Predicate<Cursor> filter) {
+    public List<DocumentInfo> loadDocuments(Selection<String> selection, Predicate<Cursor> filter) {
         final int size = (selection != null) ? selection.size() : 0;
 
         final List<DocumentInfo> docs =  new ArrayList<>(size);
@@ -228,7 +225,7 @@
         return docs;
     }
 
-    public boolean hasDocuments(Selection selection, Predicate<Cursor> filter) {
+    public boolean hasDocuments(Selection<String> selection, Predicate<Cursor> filter) {
         for (String modelId: selection) {
             if (loadDocument(modelId, filter) != null) {
                 return true;
diff --git a/src/com/android/documentsui/ModelId.java b/src/com/android/documentsui/ModelId.java
new file mode 100644
index 0000000..e178c63
--- /dev/null
+++ b/src/com/android/documentsui/ModelId.java
@@ -0,0 +1,68 @@
+package com.android.documentsui;
+
+import static com.android.documentsui.base.DocumentInfo.getCursorString;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.util.Log;
+
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.roots.RootCursorWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ModelId {
+    private final static String TAG = "ModelId";
+
+    public static final String build(Uri uri) {
+        String documentId;
+        try {
+            documentId = DocumentsContract.getDocumentId(uri);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Failed to get document id.", e);
+            return null;
+        }
+        String authority;
+        authority = uri.getAuthority();
+        return ModelId.build(authority, documentId);
+    }
+
+    public static final String build(DocumentInfo docInfo) {
+        if (docInfo == null) {
+            return null;
+        }
+        return ModelId.build(docInfo.authority, docInfo.documentId);
+    }
+
+    public static final String build(Cursor cursor) {
+        if (cursor == null) {
+            return null;
+        }
+        return ModelId.build(getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY),
+                getCursorString(cursor, DocumentsContract.Document.COLUMN_DOCUMENT_ID));
+    }
+
+    public static final ArrayList<String> build(ArrayList<Uri> uris) {
+        if (uris == null || uris.isEmpty()) {
+            return null;
+        }
+        ArrayList<String> ids = new ArrayList<>();
+        String id;
+        for (Uri uri : uris) {
+            id = ModelId.build(uri);
+            if (id != null) {
+                ids.add(id);
+            }
+        }
+        return ids;
+    }
+
+    public static final String build(String authority, String docId) {
+        if (authority == null || authority.isEmpty() || docId == null || docId.isEmpty()) {
+            return null;
+        }
+        return authority + "|" + docId;
+    }
+}
diff --git a/src/com/android/documentsui/MultiRootDocumentsLoader.java b/src/com/android/documentsui/MultiRootDocumentsLoader.java
new file mode 100644
index 0000000..777efe0
--- /dev/null
+++ b/src/com/android/documentsui/MultiRootDocumentsLoader.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2018 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.documentsui;
+
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
+import static com.android.documentsui.base.SharedMinimal.TAG;
+
+import android.app.ActivityManager;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.CursorWrapper;
+import android.database.MatrixCursor;
+import android.database.MergeCursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.loader.content.AsyncTaskLoader;
+
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.FilteringCursorWrapper;
+import com.android.documentsui.base.Lookup;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.State;
+import com.android.documentsui.roots.ProvidersAccess;
+import com.android.documentsui.roots.RootCursorWrapper;
+
+import com.google.common.util.concurrent.AbstractFuture;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/*
+ * The abstract class to query multiple roots from {@link android.provider.DocumentsProvider}
+ * and return the combined result.
+ */
+public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<DirectoryResult> {
+    // TODO: clean up cursor ownership so background thread doesn't traverse
+    // previously returned cursors for filtering/sorting; this currently races
+    // with the UI thread.
+
+    private static final int MAX_OUTSTANDING_TASK = 4;
+    private static final int MAX_OUTSTANDING_TASK_SVELTE = 2;
+
+    /**
+     * Time to wait for first pass to complete before returning partial results.
+     */
+    private static final int MAX_FIRST_PASS_WAIT_MILLIS = 500;
+
+    protected final State mState;
+
+    private final Semaphore mQueryPermits;
+    private final ProvidersAccess mProviders;
+    private final Lookup<String, Executor> mExecutors;
+    private final Lookup<String, String> mFileTypeMap;
+
+    @GuardedBy("mTasks")
+    /** A authority -> QueryTask map */
+    private final Map<String, QueryTask> mTasks = new HashMap<>();
+
+    private CountDownLatch mFirstPassLatch;
+    private volatile boolean mFirstPassDone;
+
+    private DirectoryResult mResult;
+
+    /*
+     * Create the loader to query roots from {@link android.provider.DocumentsProvider}.
+     *
+     * @param context the context
+     * @param providers the providers
+     * @param state current state
+     * @param executors the executors of authorities
+     * @param fileTypeMap the map of mime types and file types.
+     */
+    public MultiRootDocumentsLoader(Context context, ProvidersAccess providers, State state,
+            Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap) {
+
+        super(context);
+        mProviders = providers;
+        mState = state;
+        mExecutors = executors;
+        mFileTypeMap = fileTypeMap;
+
+        // Keep clients around on high-RAM devices, since we'd be spinning them
+        // up moments later to fetch thumbnails anyway.
+        final ActivityManager am = (ActivityManager) getContext().getSystemService(
+                Context.ACTIVITY_SERVICE);
+        mQueryPermits = new Semaphore(
+                am.isLowRamDevice() ? MAX_OUTSTANDING_TASK_SVELTE : MAX_OUTSTANDING_TASK);
+    }
+
+    @Override
+    public DirectoryResult loadInBackground() {
+        synchronized (mTasks) {
+            return loadInBackgroundLocked();
+        }
+    }
+
+    private DirectoryResult loadInBackgroundLocked() {
+        if (mFirstPassLatch == null) {
+            // First time through we kick off all the recent tasks, and wait
+            // around to see if everyone finishes quickly.
+            Map<String, List<RootInfo>> rootsIndex = indexRoots();
+
+            for (Map.Entry<String, List<RootInfo>> rootEntry : rootsIndex.entrySet()) {
+                mTasks.put(rootEntry.getKey(),
+                        getQueryTask(rootEntry.getKey(), rootEntry.getValue()));
+            }
+
+            mFirstPassLatch = new CountDownLatch(mTasks.size());
+            for (QueryTask task : mTasks.values()) {
+                mExecutors.lookup(task.authority).execute(task);
+            }
+
+            try {
+                mFirstPassLatch.await(MAX_FIRST_PASS_WAIT_MILLIS, TimeUnit.MILLISECONDS);
+                mFirstPassDone = true;
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        final long rejectBefore = getRejectBeforeTime();
+
+        // Collect all finished tasks
+        boolean allDone = true;
+        int totalQuerySize = 0;
+        List<Cursor> cursors = new ArrayList<>(mTasks.size());
+        for (QueryTask task : mTasks.values()) {
+            if (task.isDone()) {
+                try {
+                    final Cursor[] taskCursors = task.get();
+                    if (taskCursors == null || taskCursors.length == 0) {
+                        continue;
+                    }
+
+                    totalQuerySize += taskCursors.length;
+                    for (Cursor cursor : taskCursors) {
+                        if (cursor == null) {
+                            // It's possible given an authority, some roots fail to return a cursor
+                            // after a query.
+                            continue;
+                        }
+                        final FilteringCursorWrapper filtered = new FilteringCursorWrapper(
+                                cursor, mState.acceptMimes, getRejectMimes(), rejectBefore) {
+                            @Override
+                            public void close() {
+                                // Ignored, since we manage cursor lifecycle internally
+                            }
+                        };
+                        cursors.add(filtered);
+                    }
+
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                } catch (ExecutionException e) {
+                    // We already logged on other side
+                } catch (Exception e) {
+                    // Catch exceptions thrown when we read the cursor.
+                    Log.e(TAG, "Failed to query documents for authority: " + task.authority
+                            + ". Skip this authority.", e);
+                }
+            } else {
+                allDone = false;
+            }
+        }
+
+        if (DEBUG) {
+            Log.d(TAG,
+                    "Found " + cursors.size() + " of " + totalQuerySize + " queries done");
+        }
+
+        final DirectoryResult result = new DirectoryResult();
+        result.doc = new DocumentInfo();
+
+        final Cursor merged;
+        if (cursors.size() > 0) {
+            merged = new MergeCursor(cursors.toArray(new Cursor[cursors.size()]));
+        } else {
+            // Return something when nobody is ready
+            merged = new MatrixCursor(new String[0]);
+        }
+
+        final Cursor sorted;
+        if (isDocumentsMovable()) {
+            sorted = mState.sortModel.sortCursor(merged, mFileTypeMap);
+        } else {
+            final Cursor notMovableMasked = new NotMovableMaskCursor(merged);
+            sorted = mState.sortModel.sortCursor(notMovableMasked, mFileTypeMap);
+        }
+
+        // Tell the UI if this is an in-progress result. When loading is complete, another update is
+        // sent with EXTRA_LOADING set to false.
+        Bundle extras = new Bundle();
+        extras.putBoolean(DocumentsContract.EXTRA_LOADING, !allDone);
+        sorted.setExtras(extras);
+
+        result.cursor = sorted;
+
+        return result;
+    }
+
+    /**
+     * Returns a map of Authority -> rootInfos.
+     */
+    private Map<String, List<RootInfo>> indexRoots() {
+        final Collection<RootInfo> roots = mProviders.getMatchingRootsBlocking(mState);
+        HashMap<String, List<RootInfo>> rootsIndex = new HashMap<>();
+        for (RootInfo root : roots) {
+            // ignore the root with authority is null. e.g. Recent
+            if (root.authority == null || shouldIgnoreRoot(root)) {
+                continue;
+            }
+
+            if (!rootsIndex.containsKey(root.authority)) {
+                rootsIndex.put(root.authority, new ArrayList<>());
+            }
+            rootsIndex.get(root.authority).add(root);
+        }
+
+        return rootsIndex;
+    }
+
+    protected long getRejectBeforeTime() {
+        return -1;
+    }
+
+    protected String[] getRejectMimes() {
+        return null;
+    }
+
+    protected boolean shouldIgnoreRoot(RootInfo root) {
+        return false;
+    }
+
+    protected boolean isDocumentsMovable() {
+        return false;
+    }
+
+    protected abstract QueryTask getQueryTask(String authority, List<RootInfo> rootInfos);
+
+    @Override
+    public void deliverResult(DirectoryResult result) {
+        if (isReset()) {
+            FileUtils.closeQuietly(result);
+            return;
+        }
+        DirectoryResult oldResult = mResult;
+        mResult = result;
+
+        if (isStarted()) {
+            super.deliverResult(result);
+        }
+
+        if (oldResult != null && oldResult != result) {
+            FileUtils.closeQuietly(oldResult);
+        }
+    }
+
+    @Override
+    protected void onStartLoading() {
+        if (mResult != null) {
+            deliverResult(mResult);
+        }
+        if (takeContentChanged() || mResult == null) {
+            forceLoad();
+        }
+    }
+
+    @Override
+    protected void onStopLoading() {
+        cancelLoad();
+    }
+
+    @Override
+    public void onCanceled(DirectoryResult result) {
+        FileUtils.closeQuietly(result);
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+
+        // Ensure the loader is stopped
+        onStopLoading();
+
+        synchronized (mTasks) {
+            for (QueryTask task : mTasks.values()) {
+                FileUtils.closeQuietly(task);
+            }
+        }
+
+        FileUtils.closeQuietly(mResult);
+        mResult = null;
+    }
+
+    // TODO: create better transfer of ownership around cursor to ensure its
+    // closed in all edge cases.
+
+    private static class NotMovableMaskCursor extends CursorWrapper {
+        private static final int NOT_MOVABLE_MASK =
+                ~(Document.FLAG_SUPPORTS_DELETE
+                        | Document.FLAG_SUPPORTS_REMOVE
+                        | Document.FLAG_SUPPORTS_MOVE);
+
+        private NotMovableMaskCursor(Cursor cursor) {
+            super(cursor);
+        }
+
+        @Override
+        public int getInt(int index) {
+            final int flagIndex = getWrappedCursor().getColumnIndex(Document.COLUMN_FLAGS);
+            final int value = super.getInt(index);
+            return (index == flagIndex) ? (value & NOT_MOVABLE_MASK) : value;
+        }
+    }
+
+    protected abstract class QueryTask extends AbstractFuture<Cursor[]> implements Runnable,
+            Closeable {
+        public final String authority;
+        public final List<RootInfo> rootInfos;
+
+        private Cursor[] mCursors;
+        private boolean mIsClosed = false;
+
+        public QueryTask(String authority, List<RootInfo> rootInfos) {
+            this.authority = authority;
+            this.rootInfos = rootInfos;
+        }
+
+        @Override
+        public void run() {
+            if (isCancelled()) {
+                return;
+            }
+
+            try {
+                mQueryPermits.acquire();
+            } catch (InterruptedException e) {
+                return;
+            }
+
+            try {
+                runInternal();
+            } finally {
+                mQueryPermits.release();
+            }
+        }
+
+        protected abstract Uri getQueryUri(RootInfo rootInfo);
+
+        protected abstract RootCursorWrapper generateResultCursor(RootInfo rootInfo,
+                Cursor oriCursor);
+
+        protected void addQueryArgs(@NonNull Bundle queryArgs) {
+        }
+
+        private synchronized void runInternal() {
+            if (mIsClosed) {
+                return;
+            }
+
+            ContentProviderClient client = null;
+            try {
+                client = DocumentsApplication.acquireUnstableProviderOrThrow(
+                        getContext().getContentResolver(), authority);
+
+                final int rootInfoCount = rootInfos.size();
+                final Cursor[] res = new Cursor[rootInfoCount];
+                mCursors = new Cursor[rootInfoCount];
+
+                for (int i = 0; i < rootInfoCount; i++) {
+                    final Uri uri = getQueryUri(rootInfos.get(i));
+                    try {
+                        final Bundle queryArgs = new Bundle();
+                        mState.sortModel.addQuerySortArgs(queryArgs);
+                        addQueryArgs(queryArgs);
+                        res[i] = client.query(uri, null, queryArgs, null);
+                        mCursors[i] = generateResultCursor(rootInfos.get(i), res[i]);
+                    } catch (Exception e) {
+                        Log.w(TAG, "Failed to load " + authority + ", " + rootInfos.get(i).rootId,
+                                e);
+                    }
+                }
+
+            } catch (Exception e) {
+                Log.w(TAG, "Failed to acquire content resolver for authority: " + authority);
+            } finally {
+                FileUtils.closeQuietly(client);
+            }
+
+            set(mCursors);
+
+            mFirstPassLatch.countDown();
+            if (mFirstPassDone) {
+                onContentChanged();
+            }
+        }
+
+        @Override
+        public synchronized void close() throws IOException {
+            if (mCursors == null) {
+                return;
+            }
+
+            for (Cursor cursor : mCursors) {
+                FileUtils.closeQuietly(cursor);
+            }
+
+            mIsClosed = true;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/NavigationViewManager.java b/src/com/android/documentsui/NavigationViewManager.java
index fdaba38..c2fc76a 100644
--- a/src/com/android/documentsui/NavigationViewManager.java
+++ b/src/com/android/documentsui/NavigationViewManager.java
@@ -18,16 +18,25 @@
 
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
-import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.Outline;
 import android.graphics.drawable.Drawable;
 import android.util.Log;
 import android.view.View;
-import android.widget.Toolbar;
+import android.view.ViewOutlineProvider;
 
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar;
+
+import com.android.documentsui.R;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.AnimationView;
 
+import com.google.android.material.appbar.AppBarLayout;
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+
 import java.util.function.IntConsumer;
 
 /**
@@ -42,15 +51,20 @@
     private final State mState;
     private final NavigationViewManager.Environment mEnv;
     private final Breadcrumb mBreadcrumb;
+    private final View mSearchBarView;
+    private final CollapsingToolbarLayout mCollapsingBarLayout;
+    private final Drawable mDefaultActionBarBackground;
+    private final ViewOutlineProvider mSearchBarOutlineProvider;
+    private final boolean mShowSearchBar;
 
     public NavigationViewManager(
+            Activity activity,
             DrawerController drawer,
-            Toolbar toolbar,
             State state,
             NavigationViewManager.Environment env,
             Breadcrumb breadcrumb) {
 
-        mToolbar = toolbar;
+        mToolbar = activity.findViewById(R.id.toolbar);
         mDrawer = drawer;
         mState = state;
         mEnv = env;
@@ -64,6 +78,28 @@
                         onNavigationIconClicked();
                     }
                 });
+        mSearchBarView = activity.findViewById(R.id.searchbar_title);
+        mCollapsingBarLayout = activity.findViewById(R.id.collapsing_toolbar);
+        mDefaultActionBarBackground = mToolbar.getBackground();
+        mShowSearchBar = activity.getResources().getBoolean(R.bool.show_search_bar);
+
+        final Resources resources = mToolbar.getResources();
+        final int radius = resources.getDimensionPixelSize(R.dimen.search_bar_radius);
+        final int marginStart =
+                resources.getDimensionPixelSize(R.dimen.search_bar_background_margin_start);
+        final int marginEnd =
+                resources.getDimensionPixelSize(R.dimen.search_bar_background_margin_end);
+        mSearchBarOutlineProvider = new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRoundRect(marginStart, 0,
+                        view.getWidth() - marginEnd, view.getHeight(), radius);
+            }
+        };
+    }
+
+    public void setSearchBarClickListener(View.OnClickListener listener) {
+        mSearchBarView.setOnClickListener(listener);
     }
 
     private void onNavigationIconClicked() {
@@ -84,6 +120,8 @@
     }
 
     public void update() {
+        updateScrollFlag();
+        updateToolbar();
 
         // TODO: Looks to me like this block is never getting hit.
         if (mEnv.isSearchExpanded()) {
@@ -97,18 +135,60 @@
         mToolbar.setNavigationIcon(getActionBarIcon());
         mToolbar.setNavigationContentDescription(R.string.drawer_open);
 
-        if (mState.stack.size() <= 1) {
+        if (shouldShowSearchBar()) {
             mBreadcrumb.show(false);
+            mToolbar.setTitle(null);
+            mSearchBarView.setVisibility(View.VISIBLE);
+        } else if (mState.stack.size() <= 1) {
+            mBreadcrumb.show(false);
+            mSearchBarView.setVisibility(View.GONE);
             String title = mEnv.getCurrentRoot().title;
             if (VERBOSE) Log.v(TAG, "New toolbar title is: " + title);
             mToolbar.setTitle(title);
         } else {
             mBreadcrumb.show(true);
             mToolbar.setTitle(null);
+            mSearchBarView.setVisibility(View.GONE);
             mBreadcrumb.postUpdate();
         }
+    }
 
-        if (VERBOSE) Log.v(TAG, "Final toolbar title is: " + mToolbar.getTitle());
+    private void updateScrollFlag() {
+        if (mCollapsingBarLayout == null) {
+            return;
+        }
+
+        AppBarLayout.LayoutParams lp =
+                (AppBarLayout.LayoutParams) mCollapsingBarLayout.getLayoutParams();
+        if (shouldShowSearchBar()) {
+            lp.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
+                            | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
+                            | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED);
+        } else {
+            lp.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
+                            | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
+        }
+        mCollapsingBarLayout.setLayoutParams(lp);
+    }
+
+    private void updateToolbar() {
+        if (shouldShowSearchBar()) {
+            mToolbar.setBackgroundResource(R.drawable.search_bar_background);
+            mToolbar.setOutlineProvider(mSearchBarOutlineProvider);
+        } else {
+            mToolbar.setBackground(mDefaultActionBarBackground);
+            mToolbar.setOutlineProvider(null);
+        }
+
+        if (mCollapsingBarLayout != null) {
+            View overlayBackground =
+                    mCollapsingBarLayout.findViewById(R.id.toolbar_background_layout);
+            overlayBackground.setVisibility(shouldShowSearchBar() ? View.GONE : View.VISIBLE);
+        }
+    }
+
+    private boolean shouldShowSearchBar() {
+        return mState.stack.isRecents() && !mEnv.isSearchExpanded() && mShowSearchBar;
     }
 
     // Hamburger if drawer is present, else sad nullness.
diff --git a/src/com/android/documentsui/OperationDialogFragment.java b/src/com/android/documentsui/OperationDialogFragment.java
index c13fea0..bc98662 100644
--- a/src/com/android/documentsui/OperationDialogFragment.java
+++ b/src/com/android/documentsui/OperationDialogFragment.java
@@ -16,23 +16,25 @@
 
 package com.android.documentsui;
 
-import android.annotation.IntDef;
 import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
 import android.content.DialogInterface;
 import android.net.Uri;
 import android.os.Bundle;
-import android.support.v7.app.AlertDialog;
 import android.text.Html;
 
+import androidx.annotation.IntDef;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.ui.MessageBuilder;
 
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -92,7 +94,7 @@
         final ArrayList<DocumentInfo> docList = getArguments().getParcelableArrayList(
                 FileOperationService.EXTRA_FAILED_DOCS);
 
-        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
         final String message = new MessageBuilder(getContext()).generateListMessage(
                 dialogType, operationType, docList, uriList);
 
diff --git a/src/com/android/documentsui/PackageReceiver.java b/src/com/android/documentsui/PackageReceiver.java
index e917369..3153e9b 100644
--- a/src/com/android/documentsui/PackageReceiver.java
+++ b/src/com/android/documentsui/PackageReceiver.java
@@ -23,11 +23,9 @@
 import android.net.Uri;
 
 import com.android.documentsui.picker.LastAccessedProvider;
-import com.android.documentsui.prefs.ScopedAccessLocalPreferences;
 
 /**
- * Clean up {@link LastAccessedProvider} and {@link ScopedAccessLocalPreferences} when packages
- * are removed.
+ * Clean up {@link LastAccessedProvider} when packages are removed.
  */
 public class PackageReceiver extends BroadcastReceiver {
     @Override
@@ -44,16 +42,12 @@
                     LastAccessedProvider.METHOD_PURGE,
                     null,
                     null);
-            if (packageName != null) {
-                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
-            }
         } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
             if (packageName != null) {
                 resolver.call(
                         LastAccessedProvider.buildLastAccessed(packageName),
                         LastAccessedProvider.METHOD_PURGE_PACKAGE,
                         packageName, null);
-                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
             }
         }
     }
diff --git a/src/com/android/documentsui/PreBootReceiver.java b/src/com/android/documentsui/PreBootReceiver.java
new file mode 100644
index 0000000..a983adc
--- /dev/null
+++ b/src/com/android/documentsui/PreBootReceiver.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 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.documentsui;
+
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.util.Log;
+
+import com.android.documentsui.theme.ThemeOverlayManager;
+
+/**
+ * A receiver listening action.PRE_BOOT_COMPLETED event for setting component enable or disable.
+ * Since there's limitation of overlay AndroidManifest.xml attrs at boot stage.
+ * The workaround to retrieve config from DocumentsUI RRO package at boot time in Q.
+ */
+public class PreBootReceiver extends BroadcastReceiver {
+
+    private static final String TAG = "PreBootReceiver";
+    private static final String CONFIG_IS_LAUNCHER_ENABLED = "is_launcher_enabled";
+    private static final String CONFIG_HANDLE_VIEW_DOWNLOADS = "handle_view_downloads_intent";
+    private static final String LAUNCHER_TARGET_CLASS = "com.android.documentsui.LauncherActivity";
+    private static final String DOWNLOADS_TARGET_CLASS =
+            "com.android.documentsui.ViewDownloadsActivity";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final PackageManager pm = context.getPackageManager();
+        if (pm == null) {
+            Log.w(TAG, "Can't obtain PackageManager from System Service!");
+            return;
+        }
+
+        final OverlayManager om = context.getSystemService(OverlayManager.class);
+        if (om == null) {
+            Log.w(TAG, "Can't obtain OverlayManager from System Service!");
+            return;
+        }
+
+        final OverlayInfo info = new ThemeOverlayManager(om,
+                context.getPackageName()).getValidOverlay(pm);
+
+        if (info == null) {
+            Log.w(TAG, "Can't get valid overlay info");
+            return;
+        }
+
+        final String overlayPkg = info.getPackageName();
+        final String packageName = context.getPackageName();
+
+        Resources overlayRes;
+        try {
+            overlayRes = pm.getResourcesForApplication(overlayPkg);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Failed while parse package res.");
+            overlayRes = null;
+        }
+        if (overlayRes == null) {
+            return;
+        }
+
+        setComponentEnabledByConfigResources(pm, packageName, LAUNCHER_TARGET_CLASS,
+                overlayPkg, overlayRes, CONFIG_IS_LAUNCHER_ENABLED);
+        setComponentEnabledByConfigResources(pm, packageName, DOWNLOADS_TARGET_CLASS,
+                overlayPkg, overlayRes, CONFIG_HANDLE_VIEW_DOWNLOADS);
+    }
+
+    private static void setComponentEnabledByConfigResources(PackageManager pm, String packageName,
+            String className, String overlayPkg, Resources overlayRes, String config) {
+        int resId = overlayRes.getIdentifier(config, "bool", overlayPkg);
+        if (resId != 0) {
+            final ComponentName component = new ComponentName(packageName, className);
+            final boolean value = overlayRes.getBoolean(resId);
+            if (DEBUG) {
+                Log.i(TAG, "Overlay package:" + overlayPkg + ", customize " + config + ":" + value);
+            }
+            pm.setComponentEnabledSetting(component, value
+                            ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+                            : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                    PackageManager.DONT_KILL_APP);
+        }
+    }
+}
diff --git a/src/com/android/documentsui/ProviderExecutor.java b/src/com/android/documentsui/ProviderExecutor.java
index 8145edc..e121832 100644
--- a/src/com/android/documentsui/ProviderExecutor.java
+++ b/src/com/android/documentsui/ProviderExecutor.java
@@ -18,7 +18,7 @@
 
 import android.os.AsyncTask;
 
-import com.android.internal.annotations.GuardedBy;
+import androidx.annotation.GuardedBy;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
diff --git a/src/com/android/documentsui/RecentsLoader.java b/src/com/android/documentsui/RecentsLoader.java
index bb0115d..f9eacaa 100644
--- a/src/com/android/documentsui/RecentsLoader.java
+++ b/src/com/android/documentsui/RecentsLoader.java
@@ -16,395 +16,73 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.documentsui.base.SharedMinimal.TAG;
-
-import android.app.ActivityManager;
-import android.content.AsyncTaskLoader;
-import android.content.ContentProviderClient;
 import android.content.Context;
 import android.database.Cursor;
-import android.database.CursorWrapper;
-import android.database.MatrixCursor;
-import android.database.MergeCursor;
 import android.net.Uri;
-import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.text.format.DateUtils;
-import android.util.Log;
 
-import com.android.documentsui.base.Features;
-import com.android.documentsui.base.FilteringCursorWrapper;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.roots.ProvidersAccess;
 import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.internal.annotations.GuardedBy;
 
-import com.google.common.util.concurrent.AbstractFuture;
-
-import libcore.io.IoUtils;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
 
-public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> {
-    // TODO: clean up cursor ownership so background thread doesn't traverse
-    // previously returned cursors for filtering/sorting; this currently races
-    // with the UI thread.
-
-    private static final int MAX_OUTSTANDING_RECENTS = 4;
-    private static final int MAX_OUTSTANDING_RECENTS_SVELTE = 2;
-
-    /**
-     * Time to wait for first pass to complete before returning partial results.
-     */
-    private static final int MAX_FIRST_PASS_WAIT_MILLIS = 500;
-
-    /** Maximum documents from a single root. */
-    private static final int MAX_DOCS_FROM_ROOT = 64;
+public class RecentsLoader extends MultiRootDocumentsLoader {
 
     /** Ignore documents older than this age. */
     private static final long REJECT_OLDER_THAN = 45 * DateUtils.DAY_IN_MILLIS;
 
     /** MIME types that should always be excluded from recents. */
-    private static final String[] RECENT_REJECT_MIMES = new String[] { Document.MIME_TYPE_DIR };
+    private static final String[] REJECT_MIMES = new String[]{Document.MIME_TYPE_DIR};
 
-    private final Semaphore mQueryPermits;
+    /** Maximum documents from a single root. */
+    private static final int MAX_DOCS_FROM_ROOT = 64;
 
-    private final ProvidersAccess mProviders;
-    private final State mState;
-    private final Features mFeatures;
-    private final Lookup<String, Executor> mExecutors;
-    private final Lookup<String, String> mFileTypeMap;
-
-    @GuardedBy("mTasks")
-    /** A authority -> RecentsTask map */
-    private final Map<String, RecentsTask> mTasks = new HashMap<>();
-
-    private CountDownLatch mFirstPassLatch;
-    private volatile boolean mFirstPassDone;
-
-    private DirectoryResult mResult;
-
-    public RecentsLoader(Context context, ProvidersAccess providers, State state, Features features,
+    public RecentsLoader(Context context, ProvidersAccess providers, State state,
             Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap) {
-
-        super(context);
-        mProviders = providers;
-        mState = state;
-        mFeatures = features;
-        mExecutors = executors;
-        mFileTypeMap = fileTypeMap;
-
-        // Keep clients around on high-RAM devices, since we'd be spinning them
-        // up moments later to fetch thumbnails anyway.
-        final ActivityManager am = (ActivityManager) getContext().getSystemService(
-                Context.ACTIVITY_SERVICE);
-        mQueryPermits = new Semaphore(
-                am.isLowRamDevice() ? MAX_OUTSTANDING_RECENTS_SVELTE : MAX_OUTSTANDING_RECENTS);
+        super(context, providers, state, executors, fileTypeMap);
     }
 
     @Override
-    public DirectoryResult loadInBackground() {
-        synchronized (mTasks) {
-            return loadInBackgroundLocked();
-        }
-    }
-
-    private DirectoryResult loadInBackgroundLocked() {
-        if (mFirstPassLatch == null) {
-            // First time through we kick off all the recent tasks, and wait
-            // around to see if everyone finishes quickly.
-            Map<String, List<String>> rootsIndex = indexRecentsRoots();
-
-            for (String authority : rootsIndex.keySet()) {
-                mTasks.put(authority, new RecentsTask(authority, rootsIndex.get(authority)));
-            }
-
-            mFirstPassLatch = new CountDownLatch(mTasks.size());
-            for (RecentsTask task : mTasks.values()) {
-                mExecutors.lookup(task.authority).execute(task);
-            }
-
-            try {
-                mFirstPassLatch.await(MAX_FIRST_PASS_WAIT_MILLIS, TimeUnit.MILLISECONDS);
-                mFirstPassDone = true;
-            } catch (InterruptedException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        final long rejectBefore = System.currentTimeMillis() - REJECT_OLDER_THAN;
-
-        // Collect all finished tasks
-        boolean allDone = true;
-        int totalQuerySize = 0;
-        List<Cursor> cursors = new ArrayList<>(mTasks.size());
-        for (RecentsTask task : mTasks.values()) {
-            if (task.isDone()) {
-                try {
-                    final Cursor[] taskCursors = task.get();
-                    if (taskCursors == null || taskCursors.length == 0) continue;
-
-                    totalQuerySize += taskCursors.length;
-                    for (Cursor cursor : taskCursors) {
-                        if (cursor == null) {
-                            // It's possible given an authority, some roots fail to return a cursor
-                            // after a query.
-                            continue;
-                        }
-                        final FilteringCursorWrapper filtered = new FilteringCursorWrapper(
-                                cursor, mState.acceptMimes, RECENT_REJECT_MIMES, rejectBefore) {
-                            @Override
-                            public void close() {
-                                // Ignored, since we manage cursor lifecycle internally
-                            }
-                        };
-                        cursors.add(filtered);
-                    }
-
-                } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
-                } catch (ExecutionException e) {
-                    // We already logged on other side
-                } catch (Exception e) {
-                    // Catch exceptions thrown when we read the cursor.
-                    Log.e(TAG, "Failed to query Recents for authority: " + task.authority
-                            + ". Skip this authority in Recents.", e);
-                }
-            } else {
-                allDone = false;
-            }
-        }
-
-        if (DEBUG) {
-            Log.d(TAG,
-                    "Found " + cursors.size() + " of " + totalQuerySize + " recent queries done");
-        }
-
-        final DirectoryResult result = new DirectoryResult();
-
-        final Cursor merged;
-        if (cursors.size() > 0) {
-            merged = new MergeCursor(cursors.toArray(new Cursor[cursors.size()]));
-        } else {
-            // Return something when nobody is ready
-            merged = new MatrixCursor(new String[0]);
-        }
-
-        final Cursor notMovableMasked = new NotMovableMaskCursor(merged);
-        final Cursor sorted = mState.sortModel.sortCursor(notMovableMasked, mFileTypeMap);
-
-        // Tell the UI if this is an in-progress result. When loading is complete, another update is
-        // sent with EXTRA_LOADING set to false.
-        Bundle extras = new Bundle();
-        extras.putBoolean(DocumentsContract.EXTRA_LOADING, !allDone);
-        sorted.setExtras(extras);
-
-        result.cursor = sorted;
-
-        return result;
-    }
-
-    /**
-     * Returns a map of Authority -> rootIds
-     */
-    private Map<String, List<String>> indexRecentsRoots() {
-        final Collection<RootInfo> roots = mProviders.getMatchingRootsBlocking(mState);
-        HashMap<String, List<String>> rootsIndex = new HashMap<>();
-        for (RootInfo root : roots) {
-            if (!root.supportsRecents()) {
-                continue;
-            }
-
-            if (!rootsIndex.containsKey(root.authority)) {
-                rootsIndex.put(root.authority, new ArrayList<>());
-            }
-            rootsIndex.get(root.authority).add(root.rootId);
-        }
-
-        return rootsIndex;
+    protected long getRejectBeforeTime() {
+        return System.currentTimeMillis() - REJECT_OLDER_THAN;
     }
 
     @Override
-    public void cancelLoadInBackground() {
-        super.cancelLoadInBackground();
+    protected String[] getRejectMimes() {
+        return REJECT_MIMES;
     }
 
     @Override
-    public void deliverResult(DirectoryResult result) {
-        if (isReset()) {
-            IoUtils.closeQuietly(result);
-            return;
-        }
-        DirectoryResult oldResult = mResult;
-        mResult = result;
-
-        if (isStarted()) {
-            super.deliverResult(result);
-        }
-
-        if (oldResult != null && oldResult != result) {
-            IoUtils.closeQuietly(oldResult);
-        }
+    protected boolean shouldIgnoreRoot(RootInfo root) {
+        // only query the root is local only and support recents
+        return !root.isLocalOnly() || !root.supportsRecents();
     }
 
     @Override
-    protected void onStartLoading() {
-        if (mResult != null) {
-            deliverResult(mResult);
-        }
-        if (takeContentChanged() || mResult == null) {
-            forceLoad();
-        }
+    protected QueryTask getQueryTask(String authority, List<RootInfo> rootInfos) {
+        return new RecentsTask(authority, rootInfos);
     }
 
-    @Override
-    protected void onStopLoading() {
-        cancelLoad();
-    }
+    private class RecentsTask extends QueryTask {
 
-    @Override
-    public void onCanceled(DirectoryResult result) {
-        IoUtils.closeQuietly(result);
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-
-        // Ensure the loader is stopped
-        onStopLoading();
-
-        synchronized (mTasks) {
-            for (RecentsTask task : mTasks.values()) {
-                IoUtils.closeQuietly(task);
-            }
-        }
-
-        IoUtils.closeQuietly(mResult);
-        mResult = null;
-    }
-
-    // TODO: create better transfer of ownership around cursor to ensure its
-    // closed in all edge cases.
-
-    private class RecentsTask extends AbstractFuture<Cursor[]> implements Runnable, Closeable {
-        public final String authority;
-        public final List<String> rootIds;
-
-        private Cursor[] mCursors;
-        private boolean mIsClosed = false;
-
-        public RecentsTask(String authority, List<String> rootIds) {
-            this.authority = authority;
-            this.rootIds = rootIds;
+        public RecentsTask(String authority, List<RootInfo> rootInfos) {
+            super(authority, rootInfos);
         }
 
         @Override
-        public void run() {
-            if (isCancelled()) return;
-
-            try {
-                mQueryPermits.acquire();
-            } catch (InterruptedException e) {
-                return;
-            }
-
-            try {
-                runInternal();
-            } finally {
-                mQueryPermits.release();
-            }
-        }
-
-        private synchronized void runInternal() {
-            if (mIsClosed) {
-                return;
-            }
-
-            ContentProviderClient client = null;
-            try {
-                client = DocumentsApplication.acquireUnstableProviderOrThrow(
-                        getContext().getContentResolver(), authority);
-
-                final Cursor[] res = new Cursor[rootIds.size()];
-                mCursors = new Cursor[rootIds.size()];
-                for (int i = 0; i < rootIds.size(); i++) {
-                    final Uri uri =
-                            DocumentsContract.buildRecentDocumentsUri(authority, rootIds.get(i));
-                    try {
-                        if (mFeatures.isContentPagingEnabled()) {
-                            final Bundle queryArgs = new Bundle();
-                            mState.sortModel.addQuerySortArgs(queryArgs);
-                            res[i] = client.query(uri, null, queryArgs, null);
-                        } else {
-                            res[i] = client.query(
-                                    uri, null, null, null, mState.sortModel.getDocumentSortQuery());
-                        }
-                        mCursors[i] = new RootCursorWrapper(authority, rootIds.get(i), res[i],
-                                MAX_DOCS_FROM_ROOT);
-                    } catch (Exception e) {
-                        Log.w(TAG, "Failed to load " + authority + ", " + rootIds.get(i), e);
-                    }
-                }
-
-            } catch (Exception e) {
-                Log.w(TAG, "Failed to acquire content resolver for authority: " + authority);
-            } finally {
-                ContentProviderClient.releaseQuietly(client);
-            }
-
-            set(mCursors);
-
-            mFirstPassLatch.countDown();
-            if (mFirstPassDone) {
-                onContentChanged();
-            }
+        protected Uri getQueryUri(RootInfo rootInfo) {
+            return DocumentsContract.buildRecentDocumentsUri(authority, rootInfo.rootId);
         }
 
         @Override
-        public synchronized void close() throws IOException {
-            if (mCursors == null) {
-                return;
-            }
-
-            for (Cursor cursor : mCursors) {
-                IoUtils.closeQuietly(cursor);
-            }
-
-            mIsClosed = true;
-        }
-    }
-
-    private static class NotMovableMaskCursor extends CursorWrapper {
-        private static final int NOT_MOVABLE_MASK =
-                ~(Document.FLAG_SUPPORTS_DELETE
-                        | Document.FLAG_SUPPORTS_REMOVE
-                        | Document.FLAG_SUPPORTS_MOVE);
-
-        private NotMovableMaskCursor(Cursor cursor) {
-            super(cursor);
-        }
-
-        @Override
-        public int getInt(int index) {
-            final int flagIndex = getWrappedCursor().getColumnIndex(Document.COLUMN_FLAGS);
-            final int value = super.getInt(index);
-            return (index == flagIndex) ? (value & NOT_MOVABLE_MASK) : value;
+        protected RootCursorWrapper generateResultCursor(RootInfo rootInfo, Cursor oriCursor) {
+            return new RootCursorWrapper(authority, rootInfo.rootId, oriCursor, MAX_DOCS_FROM_ROOT);
         }
     }
 }
diff --git a/src/com/android/documentsui/RefreshTask.java b/src/com/android/documentsui/RefreshTask.java
index 5e0a1a1..bcdfac8 100644
--- a/src/com/android/documentsui/RefreshTask.java
+++ b/src/com/android/documentsui/RefreshTask.java
@@ -18,14 +18,16 @@
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.annotation.Nullable;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
 import android.os.CancellationSignal;
+import android.os.FileUtils;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+
 import com.android.documentsui.base.ApplicationScope;
 import com.android.documentsui.base.BooleanConsumer;
 import com.android.documentsui.base.CheckedTask;
@@ -73,6 +75,11 @@
             return false;
         }
 
+        if (mDoc.derivedUri == null) {
+            Log.w(TAG, "Ignoring attempt to refresh due to null derived uri in DocumentInfo.");
+            return false;
+        }
+
         if (!mDoc.derivedUri.equals(mState.stack.peek().derivedUri)) {
             Log.w(TAG, "Ignoring attempt to refresh on a non-top-level uri.");
             return false;
@@ -97,7 +104,7 @@
         } catch (Exception e) {
             Log.w(TAG, "Failed to refresh", e);
         } finally {
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(client);
         }
         return refreshSupported;
     }
diff --git a/src/com/android/documentsui/RootsMonitor.java b/src/com/android/documentsui/RootsMonitor.java
index f1200ed..e87e53a 100644
--- a/src/com/android/documentsui/RootsMonitor.java
+++ b/src/com/android/documentsui/RootsMonitor.java
@@ -22,7 +22,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.Uri;
-import android.support.v4.content.LocalBroadcastManager;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 
 import com.android.documentsui.AbstractActionHandler.CommonAddons;
 import com.android.documentsui.base.DocumentInfo;
diff --git a/src/com/android/documentsui/ScopedAccessActivity.java b/src/com/android/documentsui/ScopedAccessActivity.java
index eca9127..425c275 100644
--- a/src/com/android/documentsui/ScopedAccessActivity.java
+++ b/src/com/android/documentsui/ScopedAccessActivity.java
@@ -16,374 +16,25 @@
 
 package com.android.documentsui;
 
-import static android.os.Environment.isStandardDirectory;
-import static android.os.storage.StorageVolume.EXTRA_DIRECTORY_NAME;
-import static android.os.storage.StorageVolume.EXTRA_STORAGE_VOLUME;
-
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_DENIED;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ERROR;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_GRANTED;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
+import static com.android.documentsui.MetricConsts.SCOPED_DIRECTORY_ACCESS_DEPRECATED;
 import static com.android.documentsui.ScopedAccessMetrics.logInvalidScopedAccessRequest;
-import static com.android.documentsui.ScopedAccessMetrics.logValidScopedAccessRequest;
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.documentsui.base.SharedMinimal.DIRECTORY_ROOT;
-import static com.android.documentsui.base.SharedMinimal.getUriPermission;
-import static com.android.documentsui.base.SharedMinimal.getInternalDirectoryName;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_ASK_AGAIN;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_NEVER_ASK;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getScopedAccessPermissionStatus;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.setScopedAccessPermissionStatus;
 
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.app.GrantedUriPermission;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.UriPermission;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.Uri;
 import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
-import android.provider.DocumentsContract;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.TextView;
-
-import com.android.documentsui.base.Providers;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
 
 /**
  * Activity responsible for handling {@link StorageVolume#createAccessIntent(String)}.
+ *
+ * @deprecated This class handles the deprecated {@link StorageVolume#createAccessIntent(String)}.
  */
+@Deprecated
 public class ScopedAccessActivity extends Activity {
-    private static final String TAG = "ScopedAccessActivity";
-    private static final String FM_TAG = "open_external_directory";
-    private static final String EXTRA_FILE = "com.android.documentsui.FILE";
-    private static final String EXTRA_APP_LABEL = "com.android.documentsui.APP_LABEL";
-    private static final String EXTRA_VOLUME_LABEL = "com.android.documentsui.VOLUME_LABEL";
-    private static final String EXTRA_VOLUME_UUID = "com.android.documentsui.VOLUME_UUID";
-    private static final String EXTRA_IS_ROOT = "com.android.documentsui.IS_ROOT";
-    private static final String EXTRA_IS_PRIMARY = "com.android.documentsui.IS_PRIMARY";
-
-    private ContentProviderClient mExternalStorageClient;
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        if (savedInstanceState != null) {
-            if (DEBUG) Log.d(TAG, "activity.onCreateDialog(): reusing instance");
-            return;
-        }
-
-        final Intent intent = getIntent();
-        if (intent == null) {
-            if (DEBUG) Log.d(TAG, "missing intent");
-            logInvalidScopedAccessRequest(this, SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS);
-            setResult(RESULT_CANCELED);
-            finish();
-            return;
-        }
-        final Parcelable storageVolume = intent.getParcelableExtra(EXTRA_STORAGE_VOLUME);
-        if (!(storageVolume instanceof StorageVolume)) {
-            if (DEBUG)
-                Log.d(TAG, "extra " + EXTRA_STORAGE_VOLUME + " is not a StorageVolume: "
-                        + storageVolume);
-            logInvalidScopedAccessRequest(this, SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS);
-            setResult(RESULT_CANCELED);
-            finish();
-            return;
-        }
-        String directoryName =
-                getInternalDirectoryName(intent.getStringExtra(EXTRA_DIRECTORY_NAME));
-        final StorageVolume volume = (StorageVolume) storageVolume;
-        final String uuid = volume.isPrimary() ? null : volume.getUuid();
-        if (getScopedAccessPermissionStatus(getApplicationContext(), getCallingPackage(),
-                uuid, directoryName) == PERMISSION_NEVER_ASK) {
-            logValidScopedAccessRequest(this, directoryName,
-                    SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED);
-            setResult(RESULT_CANCELED);
-            finish();
-            return;
-        }
-
-        final int userId = UserHandle.myUserId();
-        if (!showFragment(this, userId, volume, directoryName)) {
-            setResult(RESULT_CANCELED);
-            finish();
-            return;
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (mExternalStorageClient != null) {
-            mExternalStorageClient.close();
-        }
-    }
-
-    /**
-     * Validates the given path (volume + directory) and display the appropriate dialog asking the
-     * user to grant access to it.
-     */
-    private static boolean showFragment(ScopedAccessActivity activity, int userId,
-            StorageVolume storageVolume, String directoryName) {
-        return getUriPermission(activity,
-                activity.getExternalStorageClient(), storageVolume, directoryName, userId, true,
-                (file, volumeLabel, isRoot, isPrimary, grantedUri, rootUri) -> {
-                    // Checks if the user has granted the permission already.
-                    final Intent intent = getIntentForExistingPermission(activity,
-                            activity.getCallingPackage(), grantedUri, rootUri);
-                    if (intent != null) {
-                        logValidScopedAccessRequest(activity, isRoot ? "." : directoryName,
-                                SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED);
-                        activity.setResult(RESULT_OK, intent);
-                        activity.finish();
-                        return true;
-                    }
-
-                    // Gets the package label.
-                    final String appLabel = getAppLabel(activity);
-                    if (appLabel == null) {
-                        // Error already logged.
-                        return false;
-                    }
-
-                    // Sets args that will be retrieve on onCreate()
-                    final Bundle args = new Bundle();
-                    args.putString(EXTRA_FILE, file.getAbsolutePath());
-                    args.putString(EXTRA_VOLUME_LABEL, volumeLabel);
-                    args.putString(EXTRA_VOLUME_UUID, isPrimary ? null : storageVolume.getUuid());
-                    args.putString(EXTRA_APP_LABEL, appLabel);
-                    args.putBoolean(EXTRA_IS_ROOT, isRoot);
-                    args.putBoolean(EXTRA_IS_PRIMARY, isPrimary);
-
-                    final FragmentManager fm = activity.getFragmentManager();
-                    final FragmentTransaction ft = fm.beginTransaction();
-                    final ScopedAccessDialogFragment fragment = new ScopedAccessDialogFragment();
-                    fragment.setArguments(args);
-                    ft.add(fragment, FM_TAG);
-                    ft.commitAllowingStateLoss();
-
-                    return true;
-                });
-    }
-
-    private static String getAppLabel(Activity activity) {
-        final String packageName = activity.getCallingPackage();
-        final PackageManager pm = activity.getPackageManager();
-        try {
-            return pm.getApplicationLabel(pm.getApplicationInfo(packageName, 0)).toString();
-        } catch (NameNotFoundException e) {
-            logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_ERROR);
-            Log.w(TAG, "Could not get label for package " + packageName);
-            return null;
-        }
-    }
-
-    private static Intent createGrantedUriPermissionsIntent(Context context,
-            ContentProviderClient provider, File file) {
-        final Uri uri = getUriPermission(context, provider, file);
-        return createGrantedUriPermissionsIntent(uri);
-    }
-
-    private static Intent createGrantedUriPermissionsIntent(Uri uri) {
-        final Intent intent = new Intent();
-        intent.setData(uri);
-        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
-                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
-                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
-        return intent;
-    }
-
-    private static Intent getIntentForExistingPermission(Context context, String packageName,
-            Uri grantedUri, Uri rootUri) {
-        if (DEBUG) {
-            Log.d(TAG, "checking if " + packageName + " already has permission for " + grantedUri
-                    + " or its root (" + rootUri + ")");
-        }
-        final ActivityManager am = context.getSystemService(ActivityManager.class);
-        for (GrantedUriPermission uriPermission : am.getGrantedUriPermissions(packageName)
-                .getList()) {
-            final Uri uri = uriPermission.uri;
-            if (uri == null) {
-                Log.w(TAG, "null URI for " + uriPermission);
-                continue;
-            }
-            if (uri.equals(grantedUri) || uri.equals(rootUri)) {
-                if (DEBUG) Log.d(TAG, packageName + " already has permission: " + uriPermission);
-                return createGrantedUriPermissionsIntent(grantedUri);
-            }
-        }
-        if (DEBUG) Log.d(TAG, packageName + " does not have permission for " + grantedUri);
-        return null;
-    }
-
-    public static class ScopedAccessDialogFragment extends DialogFragment {
-
-        private File mFile;
-        private String mVolumeUuid;
-        private String mVolumeLabel;
-        private String mAppLabel;
-        private boolean mIsRoot;
-        private boolean mIsPrimary;
-        private CheckBox mDontAskAgain;
-        private ScopedAccessActivity mActivity;
-        private AlertDialog mDialog;
-
-        @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            setRetainInstance(true);
-            final Bundle args = getArguments();
-            if (args != null) {
-                mFile = new File(args.getString(EXTRA_FILE));
-                mVolumeUuid = args.getString(EXTRA_VOLUME_UUID);
-                mVolumeLabel = args.getString(EXTRA_VOLUME_LABEL);
-                mAppLabel = args.getString(EXTRA_APP_LABEL);
-                mIsRoot = args.getBoolean(EXTRA_IS_ROOT);
-                mIsPrimary= args.getBoolean(EXTRA_IS_PRIMARY);
-            }
-            mActivity = (ScopedAccessActivity) getActivity();
-        }
-
-        @Override
-        public void onDestroyView() {
-            // Workaround for https://code.google.com/p/android/issues/detail?id=17423
-            if (mDialog != null && getRetainInstance()) {
-                mDialog.setDismissMessage(null);
-            }
-            super.onDestroyView();
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            if (mDialog != null) {
-                if (DEBUG) Log.d(TAG, "fragment.onCreateDialog(): reusing dialog");
-                return mDialog;
-            }
-            if (mActivity != getActivity()) {
-                // Sanity check.
-                Log.wtf(TAG, "activity references don't match on onCreateDialog(): mActivity = "
-                        + mActivity + " , getActivity() = " + getActivity());
-                mActivity = (ScopedAccessActivity) getActivity();
-            }
-            final String directory = mFile.getName();
-            final String directoryName = mIsRoot ? DIRECTORY_ROOT : directory;
-            final Context context = mActivity.getApplicationContext();
-            final OnClickListener listener = new OnClickListener() {
-
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    Intent intent = null;
-                    if (which == DialogInterface.BUTTON_POSITIVE) {
-                        intent = createGrantedUriPermissionsIntent(mActivity,
-                                mActivity.getExternalStorageClient(), mFile);
-                    }
-                    if (which == DialogInterface.BUTTON_NEGATIVE || intent == null) {
-                        logValidScopedAccessRequest(mActivity, directoryName,
-                                SCOPED_DIRECTORY_ACCESS_DENIED);
-                        final boolean checked = mDontAskAgain.isChecked();
-                        if (checked) {
-                            logValidScopedAccessRequest(mActivity, directory,
-                                    SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST);
-                            setScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
-                                    mVolumeUuid, directoryName, PERMISSION_NEVER_ASK);
-                        } else {
-                            setScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
-                                    mVolumeUuid, directoryName, PERMISSION_ASK_AGAIN);
-                        }
-                        mActivity.setResult(RESULT_CANCELED);
-                    } else {
-                        logValidScopedAccessRequest(mActivity, directory,
-                                SCOPED_DIRECTORY_ACCESS_GRANTED);
-                        mActivity.setResult(RESULT_OK, intent);
-                    }
-                    mActivity.finish();
-                }
-            };
-
-            @SuppressLint("InflateParams")
-            // It's ok pass null ViewRoot on AlertDialogs.
-            final View view = View.inflate(mActivity, R.layout.dialog_open_scoped_directory, null);
-            final CharSequence message;
-            if (mIsRoot) {
-                message = TextUtils.expandTemplate(getText(
-                        R.string.open_external_dialog_root_request), mAppLabel, mVolumeLabel);
-            } else {
-                message = TextUtils.expandTemplate(
-                        getText(mIsPrimary ? R.string.open_external_dialog_request_primary_volume
-                                : R.string.open_external_dialog_request),
-                                mAppLabel, directory, mVolumeLabel);
-            }
-            final TextView messageField = (TextView) view.findViewById(R.id.message);
-            messageField.setText(message);
-            mDialog = new AlertDialog.Builder(mActivity, R.style.Theme_AppCompat_Light_Dialog_Alert)
-                    .setView(view)
-                    .setPositiveButton(R.string.allow, listener)
-                    .setNegativeButton(R.string.deny, listener)
-                    .create();
-
-            mDontAskAgain = (CheckBox) view.findViewById(R.id.do_not_ask_checkbox);
-            if (getScopedAccessPermissionStatus(context, mActivity.getCallingPackage(),
-                    mVolumeUuid, directoryName) == PERMISSION_ASK_AGAIN) {
-                mDontAskAgain.setVisibility(View.VISIBLE);
-                mDontAskAgain.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-
-                    @Override
-                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(!isChecked);
-                    }
-                });
-            }
-
-            return mDialog;
-        }
-
-        @Override
-        public void onCancel(DialogInterface dialog) {
-            super.onCancel(dialog);
-            final Activity activity = getActivity();
-            logValidScopedAccessRequest(activity, mFile.getName(), SCOPED_DIRECTORY_ACCESS_DENIED);
-            activity.setResult(RESULT_CANCELED);
-            activity.finish();
-        }
-    }
-
-    private synchronized ContentProviderClient getExternalStorageClient() {
-        if (mExternalStorageClient == null) {
-            mExternalStorageClient =
-                    getContentResolver().acquireContentProviderClient(Providers.AUTHORITY_STORAGE);
-        }
-        return mExternalStorageClient;
+        logInvalidScopedAccessRequest(SCOPED_DIRECTORY_ACCESS_DEPRECATED);
+        setResult(RESULT_CANCELED);
+        finish();
     }
 }
diff --git a/src/com/android/documentsui/ScopedAccessMetrics.java b/src/com/android/documentsui/ScopedAccessMetrics.java
index ec23e59..832112e 100644
--- a/src/com/android/documentsui/ScopedAccessMetrics.java
+++ b/src/com/android/documentsui/ScopedAccessMetrics.java
@@ -16,133 +16,13 @@
 
 package com.android.documentsui;
 
-import static android.os.Environment.STANDARD_DIRECTORIES;
-
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.documentsui.base.SharedMinimal.DIRECTORY_ROOT;
-
-import android.annotation.IntDef;
-import android.annotation.StringDef;
-import android.app.Activity;
-import android.content.Context;
-import android.util.Log;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * Methods for logging scoped directory access metrics.
  */
 public final class ScopedAccessMetrics {
     private static final String TAG = "ScopedAccessMetrics";
 
-    // Types for logInvalidScopedAccessRequest
-    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS =
-            "docsui_scoped_directory_access_invalid_args";
-    public static final String SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY =
-            "docsui_scoped_directory_access_invalid_dir";
-    public static final String SCOPED_DIRECTORY_ACCESS_ERROR =
-            "docsui_scoped_directory_access_error";
-
-    @StringDef(value = {
-            SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS,
-            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY,
-            SCOPED_DIRECTORY_ACCESS_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface InvalidScopedAccess{}
-
-    public static void logInvalidScopedAccessRequest(Context context,
-            @InvalidScopedAccess String type) {
-        switch (type) {
-            case SCOPED_DIRECTORY_ACCESS_INVALID_ARGUMENTS:
-            case SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY:
-            case SCOPED_DIRECTORY_ACCESS_ERROR:
-                logCount(context, type);
-                break;
-            default:
-                Log.wtf(TAG, "invalid InvalidScopedAccess: " + type);
-        }
-    }
-
-    // Types for logValidScopedAccessRequest
-    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED = 0;
-    public static final int SCOPED_DIRECTORY_ACCESS_GRANTED = 1;
-    public static final int SCOPED_DIRECTORY_ACCESS_DENIED = 2;
-    public static final int SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST = 3;
-    public static final int SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED = 4;
-
-    @IntDef(flag = true, value = {
-            SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED,
-            SCOPED_DIRECTORY_ACCESS_GRANTED,
-            SCOPED_DIRECTORY_ACCESS_DENIED,
-            SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST,
-            SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ScopedAccessGrant {}
-
-    public static void logValidScopedAccessRequest(Activity activity, String directory,
-            @ScopedAccessGrant int type) {
-        int index = -1;
-        if (DIRECTORY_ROOT.equals(directory)) {
-            index = -2;
-        } else {
-            for (int i = 0; i < STANDARD_DIRECTORIES.length; i++) {
-                if (STANDARD_DIRECTORIES[i].equals(directory)) {
-                    index = i;
-                    break;
-                }
-            }
-        }
-        final String packageName = activity.getCallingPackage();
-        switch (type) {
-            case SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_GRANTED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_DENIED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_FOLDER, index);
-                break;
-            case SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED:
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_PACKAGE, packageName);
-                MetricsLogger.action(activity, MetricsEvent
-                        .ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_DENIED_BY_FOLDER, index);
-                break;
-            default:
-                Log.wtf(TAG, "invalid ScopedAccessGrant: " + type);
-        }
-    }
-
-    /**
-     * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
-     *
-     * @param context
-     * @param name The counter to increment.
-     */
-    private static void logCount(Context context, String name) {
-        if (DEBUG) Log.d(TAG, name + ": " + 1);
-        MetricsLogger.count(context, name, 1);
+    public static void logInvalidScopedAccessRequest(@MetricConsts.InvalidScopedAccess int type) {
+        DocumentsStatsLog.write(DocumentsStatsLog.DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST, type);
     }
 }
diff --git a/src/com/android/documentsui/ScopedAccessPackageReceiver.java b/src/com/android/documentsui/ScopedAccessPackageReceiver.java
deleted file mode 100644
index 995eedc..0000000
--- a/src/com/android/documentsui/ScopedAccessPackageReceiver.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-
-import com.android.documentsui.prefs.ScopedAccessLocalPreferences;
-
-/**
- * Clean up {@link ScopedAccessLocalPreferences} when packages are removed.
- */
-public class ScopedAccessPackageReceiver extends BroadcastReceiver {
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final String action = intent.getAction();
-        final Uri data = intent.getData();
-        final String packageName = data == null ? null : data.getSchemeSpecificPart();
-
-        if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) {
-            if (packageName != null) {
-                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
-            }
-        } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
-            if (packageName != null) {
-                ScopedAccessLocalPreferences.clearPackagePreferences(context, packageName);
-            }
-        }
-    }
-}
diff --git a/src/com/android/documentsui/ScopedAccessProvider.java b/src/com/android/documentsui/ScopedAccessProvider.java
deleted file mode 100644
index 787d21e..0000000
--- a/src/com/android/documentsui/ScopedAccessProvider.java
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright (C) 2018 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.documentsui;
-
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.COL_GRANTED;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COLUMNS;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PACKAGES_COL_PACKAGE;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COLUMNS;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_DIRECTORY;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_GRANTED;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_PACKAGE;
-import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS_COL_VOLUME_UUID;
-import static android.os.Environment.isStandardDirectory;
-
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.documentsui.base.SharedMinimal.getExternalDirectoryName;
-import static com.android.documentsui.base.SharedMinimal.getInternalDirectoryName;
-import static com.android.documentsui.base.SharedMinimal.getUriPermission;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_ASK_AGAIN;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_GRANTED;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.PERMISSION_NEVER_ASK;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.clearScopedAccessPreferences;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPackages;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.getAllPermissions;
-import static com.android.documentsui.prefs.ScopedAccessLocalPreferences.setScopedAccessPermissionStatus;
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.GrantedUriPermission;
-import android.content.ContentProvider;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.provider.DocumentsContract;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.documentsui.base.Providers;
-import com.android.documentsui.prefs.ScopedAccessLocalPreferences.Permission;
-import com.android.internal.util.ArrayUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-//TODO(b/72055774): update javadoc once implementation is finished
-/**
- * Provider used to manage scoped access directory permissions.
- *
- * <p>It fetches data from 2 sources:
- *
- * <ul>
- * <li>{@link com.android.documentsui.prefs.ScopedAccessLocalPreferences} for denied permissions.
- * <li>{@link ActivityManager} for allowed permissions.
- * </ul>
- *
- * <p>And returns the results in 2 tables:
- *
- * <ul>
- * <li>{@link #TABLE_PACKAGES}: read-only table with the name of all packages
- * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_PACKAGE}) that
- * had a scoped access directory permission granted or denied.
- * <li>{@link #TABLE_PERMISSIONS}: writable table with the name of all packages
- * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_PACKAGE}) that
- * had a scoped access directory
- * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_DIRECTORY})
- * permission for a volume (column
- * {@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_VOLUME_UUID}, which
- * contains the volume UUID or {@code null} if it's the primary partition) granted or denied
- * (column ({@link android.os.storage.StorageVolume.ScopedAccessProviderContract#COL_GRANTED}).
- * </ul>
- *
- * <p><b>Note:</b> the {@code query()} methods return all entries; it does not support selection or
- * projections.
- */
-// TODO(b/72055774): add unit tests
-public class ScopedAccessProvider extends ContentProvider {
-
-    private static final String TAG = "ScopedAccessProvider";
-    private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
-    private static final int URI_PACKAGES = 1;
-    private static final int URI_PERMISSIONS = 2;
-
-    public static final String AUTHORITY = "com.android.documentsui.scopedAccess";
-
-    static {
-        sMatcher.addURI(AUTHORITY, TABLE_PACKAGES + "/*", URI_PACKAGES);
-        sMatcher.addURI(AUTHORITY, TABLE_PERMISSIONS + "/*", URI_PERMISSIONS);
-    }
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        if (DEBUG) {
-            Log.v(TAG, "query(" + uri + "): proj=" + Arrays.toString(projection)
-                + ", sel=" + selection);
-        }
-        switch (sMatcher.match(uri)) {
-            case URI_PACKAGES:
-                return getPackagesCursor();
-            case URI_PERMISSIONS:
-                if (ArrayUtils.isEmpty(selectionArgs)) {
-                    throw new UnsupportedOperationException("selections cannot be empty");
-                }
-                // For simplicity, we only support one package (which is what Settings is passing).
-                if (selectionArgs.length > 1) {
-                    Log.w(TAG, "Using just first entry of " + Arrays.toString(selectionArgs));
-                }
-                return getPermissionsCursor(selectionArgs[0]);
-            default:
-                throw new UnsupportedOperationException("Unsupported Uri " + uri);
-        }
-    }
-
-    private Cursor getPackagesCursor() {
-        final Context context = getContext();
-
-        // First, get the packages that were denied
-        final Set<String> pkgs = getAllPackages(context);
-
-        // Second, query AM to get all packages that have a permission.
-        final ActivityManager am =
-                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-
-        final List<GrantedUriPermission> amPkgs = am.getGrantedUriPermissions(null).getList();
-        if (!amPkgs.isEmpty()) {
-            amPkgs.forEach((perm) -> pkgs.add(perm.packageName));
-        }
-
-        if (ArrayUtils.isEmpty(pkgs)) {
-            if (DEBUG) Log.v(TAG, "getPackagesCursor(): nothing to do" );
-            return null;
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "getPackagesCursor(): denied=" + pkgs + ", granted=" + amPkgs);
-        }
-
-        // Finally, create the cursor
-        final MatrixCursor cursor = new MatrixCursor(TABLE_PACKAGES_COLUMNS, pkgs.size());
-        pkgs.forEach((pkg) -> cursor.addRow( new Object[] { pkg }));
-        return cursor;
-    }
-
-    // TODO(b/72055774): need to unit tests to handle scenarios where the root permission of
-    // a secondary volume mismatches a child permission (for example, child is allowed by root
-    // is denied).
-    private Cursor getPermissionsCursor(String packageName) {
-        final Context context = getContext();
-
-        // List of volumes that were granted by AM at the root level - in that case,
-        // we can ignored individual grants from AM or denials from our preferences
-        final Set<String> grantedVolumes = new ArraySet<>();
-
-        // List of directories (mapped by volume uuid) that were granted by AM so they can be
-        // ignored if also found on our preferences
-        final Map<String, Set<String>> grantedDirsByUuid = new HashMap<>();
-
-        // Cursor rows
-        final List<Object[]> permissions = new ArrayList<>();
-
-        // First, query AM to get all packages that have a permission.
-        final ActivityManager am =
-                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        final List<GrantedUriPermission> uriPermissions =
-                am.getGrantedUriPermissions(packageName).getList();
-        if (DEBUG) {
-            Log.v(TAG, "am returned =" + uriPermissions);
-        }
-        setGrantedPermissions(packageName, uriPermissions, permissions, grantedVolumes,
-                grantedDirsByUuid);
-
-        // Now  gets the packages that were denied
-        final List<Permission> rawPermissions = getAllPermissions(context);
-
-        if (DEBUG) {
-            Log.v(TAG, "rawPermissions: " + rawPermissions);
-        }
-
-        // Merge the permissions granted by AM with the denied permissions saved on our preferences.
-        for (Permission rawPermission : rawPermissions) {
-            if (!packageName.equals(rawPermission.pkg)) {
-                if (DEBUG) {
-                    Log.v(TAG,
-                            "ignoring " + rawPermission + " because package is not " + packageName);
-                }
-                continue;
-            }
-            if (rawPermission.status != PERMISSION_NEVER_ASK
-                    && rawPermission.status != PERMISSION_ASK_AGAIN) {
-                // We only care for status where the user denied a request.
-                if (DEBUG) {
-                    Log.v(TAG, "ignoring " + rawPermission + " because of its status");
-                }
-                continue;
-            }
-            if (grantedVolumes.contains(rawPermission.uuid)) {
-                if (DEBUG) {
-                    Log.v(TAG, "ignoring " + rawPermission + " because whole volume is granted");
-                }
-                continue;
-            }
-            final Set<String> grantedDirs = grantedDirsByUuid.get(rawPermission.uuid);
-            if (grantedDirs != null
-                    && grantedDirs.contains(rawPermission.directory)) {
-                Log.w(TAG, "ignoring " + rawPermission + " because it was granted already");
-                continue;
-            }
-            permissions.add(new Object[] {
-                    packageName, rawPermission.uuid,
-                    getExternalDirectoryName(rawPermission.directory), 0
-            });
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "total permissions: " + permissions.size());
-        }
-
-        // Then create the cursor
-        final MatrixCursor cursor = new MatrixCursor(TABLE_PERMISSIONS_COLUMNS, permissions.size());
-        permissions.forEach((row) -> cursor.addRow(row));
-        return cursor;
-    }
-
-    /**
-     * Converts the permissions returned by AM and add it to 3 buckets ({@code permissions},
-     * {@code grantedVolumes}, and {@code grantedDirsByUuid}).
-     *
-     * @param packageName name of package that the permissions were granted to.
-     * @param uriPermissions permissions returend by AM
-     * @param permissions list of permissions that can be converted to a {@link #TABLE_PERMISSIONS}
-     * row.
-     * @param grantedVolumes volume uuids that were granted full access.
-     * @param grantedDirsByUuid directories that were granted individual acces (key is volume uuid,
-     * value is list of directories).
-     */
-    private void setGrantedPermissions(String packageName, List<GrantedUriPermission> uriPermissions,
-            List<Object[]> permissions, Set<String> grantedVolumes,
-            Map<String, Set<String>> grantedDirsByUuid) {
-        final List<Permission> grantedPermissions = parseGrantedPermissions(uriPermissions);
-
-        for (Permission p : grantedPermissions) {
-            // First check if it's for the full volume
-            if (p.directory == null) {
-                if (p.uuid == null) {
-                    // Should never happen - the Scoped Directory Access API does not allow it.
-                    Log.w(TAG, "ignoring entry whose uuid and directory is null");
-                    continue;
-                }
-                grantedVolumes.add(p.uuid);
-            } else {
-                if (!ArrayUtils.contains(Environment.STANDARD_DIRECTORIES, p.directory)) {
-                    if (DEBUG) Log.v(TAG, "Ignoring non-standard directory on " + p);
-                    continue;
-                }
-
-                Set<String> dirs = grantedDirsByUuid.get(p.uuid);
-                if (dirs == null) {
-                    // Life would be so much easier if Android had MultiMaps...
-                    dirs = new HashSet<>(1);
-                    grantedDirsByUuid.put(p.uuid, dirs);
-                }
-                dirs.add(p.directory);
-            }
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "grantedVolumes=" + grantedVolumes
-                    + ", grantedDirectories=" + grantedDirsByUuid);
-        }
-        // Add granted permissions to full volumes.
-        grantedVolumes.forEach((uuid) -> permissions.add(new Object[] {
-                packageName, uuid, /* dir= */ null, 1
-        }));
-
-        // Add granted permissions to individual directories
-        grantedDirsByUuid.forEach((uuid, dirs) -> {
-            if (grantedVolumes.contains(uuid)) {
-                Log.w(TAG, "Ignoring individual grants to " + uuid + ": " + dirs);
-            } else {
-                dirs.forEach((dir) -> permissions.add(new Object[] {packageName, uuid, dir, 1}));
-            }
-        });
-    }
-
-    /**
-     * Converts the permissions returned by AM to our own format.
-     */
-    private List<Permission> parseGrantedPermissions(List<GrantedUriPermission> uriPermissions) {
-        final List<Permission> permissions = new ArrayList<>(uriPermissions.size());
-        // TODO(b/72055774): we should query AUTHORITY_STORAGE or call DocumentsContract instead of
-        // hardcoding the logic here.
-        for (GrantedUriPermission uriPermission : uriPermissions) {
-            final Uri uri = uriPermission.uri;
-            final String authority = uri.getAuthority();
-            if (!Providers.AUTHORITY_STORAGE.equals(authority)) {
-                Log.w(TAG, "Wrong authority on " + uri);
-                continue;
-            }
-            final List<String> pathSegments = uri.getPathSegments();
-            if (pathSegments.size() < 2) {
-                Log.w(TAG, "wrong path segments on " + uri);
-                continue;
-            }
-            // TODO(b/72055774): make PATH_TREE private again if not used anymore
-            if (!DocumentsContract.PATH_TREE.equals(pathSegments.get(0))) {
-                Log.w(TAG, "wrong path tree on " + uri);
-                continue;
-            }
-
-            final String[] uuidAndDir = pathSegments.get(1).split(":");
-            // uuid and dir are either UUID:DIR (for scoped directory) or UUID: (for full volume)
-            if (uuidAndDir.length != 1 && uuidAndDir.length != 2) {
-                Log.w(TAG, "could not parse uuid and directory on " + uri);
-                continue;
-            }
-            // TODO(b/72055774): to make things uglier, the Documents directory in the primary
-            // storage is a special case as its URI is "$ROOT_ID_HOME", instead of
-            // "${ROOT_ID_DEVICE}/Documents. This is another reason to move this logic to the
-            // provider...
-            final String uuid, dir;
-            if (Providers.ROOT_ID_HOME.equals(uuidAndDir[0])) {
-                uuid = null;
-                dir = Environment.DIRECTORY_DOCUMENTS;
-            } else {
-                uuid = Providers.ROOT_ID_DEVICE.equals(uuidAndDir[0])
-                        ? null // primary
-                        : uuidAndDir[0]; // external volume
-                dir = uuidAndDir.length == 1 ? null : uuidAndDir[1];
-            }
-            permissions
-                    .add(new Permission(uriPermission.packageName, uuid, dir, PERMISSION_GRANTED));
-        }
-        return permissions;
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        return null;
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        throw new UnsupportedOperationException("insert(): unsupported " + uri);
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        if (sMatcher.match(uri) != URI_PERMISSIONS) {
-            throw new UnsupportedOperationException("delete(): unsupported " + uri);
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "delete(" + uri + "): " + Arrays.toString(selectionArgs));
-        }
-
-        // TODO(b/72055774): add unit tests for invalid input
-        checkArgument(selectionArgs != null && selectionArgs.length == 1,
-                "Must have exactly 1 args: package_name" + Arrays.toString(selectionArgs));
-        final String packageName = selectionArgs[0];
-
-        // Delete just our preferences - the URI permissions is handled externally
-        // TODO(b/72055774): move logic to revoke permissions here, so AppStorageSettings does
-        // not need to call am.clearGrantedUriPermissions(packageName) (then we could remove that
-        // method from ActivityManager)
-        return clearScopedAccessPreferences(getContext(), packageName);
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        if (sMatcher.match(uri) != URI_PERMISSIONS) {
-            throw new UnsupportedOperationException("update(): unsupported " + uri);
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "update(" + uri + "): " + Arrays.toString(selectionArgs) + " = " + values);
-        }
-
-        // TODO(b/72055774): add unit tests for invalid input
-        checkArgument(selectionArgs != null && selectionArgs.length == 3,
-                "Must have exactly 3 args: package_name, (nullable) uuid, (nullable) directory: "
-                        + Arrays.toString(selectionArgs));
-        final String packageName = selectionArgs[0];
-        final String uuid = selectionArgs[1];
-        final String dir = selectionArgs[2];
-        final boolean granted = values.getAsBoolean(COL_GRANTED);
-
-        // First update the effective URI permission ...
-        if (!persistUriPermission(packageName, uuid, dir, granted)) {
-            // Failed - nothing left to do...
-            return 0;
-        }
-
-        // ...then our preferences.
-        setScopedAccessPermissionStatus(getContext(), packageName, uuid,
-                getInternalDirectoryName(dir), granted ? PERMISSION_GRANTED : PERMISSION_NEVER_ASK);
-        return 1;
-    }
-
-    /**
-     * Calls AM to persist a URI.
-     *
-     * @return whether the call succeeded.
-     */
-    private boolean persistUriPermission(String packageName, @Nullable String uuid,
-            @Nullable String directory, boolean granted) {
-        final Context context = getContext();
-
-        final ContentProviderClient storageClient = context.getContentResolver()
-                .acquireContentProviderClient(Providers.AUTHORITY_STORAGE);
-
-        final StorageManager sm = context.getSystemService(StorageManager.class);
-
-        StorageVolume volume = null;
-        if (uuid == null) {
-            if (directory == null) {
-                Log.w(TAG, "cannot grant full access to the primary volume");
-                return false;
-            }
-            volume = sm.getPrimaryStorageVolume();
-        } else {
-            for (StorageVolume candidate : sm.getVolumeList()) {
-                if (uuid.equals(candidate.getUuid())) {
-                    volume = candidate;
-                    break;
-                }
-            }
-            if (volume == null) {
-                Log.w(TAG, "didn't find volume for UUID=" + uuid);
-                return false;
-            }
-            if (directory != null && !isStandardDirectory(directory)) {
-                Log.w(TAG, "not a scoped directory: " + directory);
-                return false;
-            }
-        }
-
-        return getUriPermission(context, storageClient, volume, getInternalDirectoryName(directory),
-                UserHandle.getCallingUserId(), /* logMetrics= */ false,
-                (file, volumeLabel, isRoot, isPrimary, grantedUri, rootUri) -> {
-                    updatePermission(context, grantedUri, packageName, granted);
-                    return true;
-                });
-    }
-
-    private void updatePermission(Context context, Uri grantedUri, String toPackage,
-            boolean granted) {
-        final int persistFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
-                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
-        final int grantFlags = persistFlags
-                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
-
-        final ContentResolver cr = context.getContentResolver();
-        if (granted) {
-            context.grantUriPermission(toPackage, grantedUri, grantFlags);
-            cr.takePersistableUriPermission(toPackage, grantedUri, persistFlags);
-        } else {
-            context.revokeUriPermission(toPackage, grantedUri, grantFlags);
-            // There's no need to release after revoking
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        final String prefix = "  ";
-
-        final List<String> packages = new ArrayList<>();
-        pw.print("Packages: ");
-        try (Cursor cursor = getPackagesCursor()) {
-            if (cursor == null || cursor.getCount() == 0) {
-                pw.println("N/A");
-            } else {
-                pw.println(cursor.getCount());
-                while (cursor.moveToNext()) {
-                    final String pkg = cursor.getString(TABLE_PACKAGES_COL_PACKAGE);
-                    packages.add(pkg);
-                    pw.print(prefix);
-                    pw.println(pkg);
-                }
-            }
-        }
-
-        pw.print("Permissions: ");
-        for (int i = 0; i < packages.size(); i++) {
-            final String pkg = packages.get(i);
-            try (Cursor cursor = getPermissionsCursor(pkg)) {
-                if (cursor == null) {
-                    pw.println("N/A");
-                } else {
-                    pw.println(cursor.getCount());
-                    while (cursor.moveToNext()) {
-                        pw.print(prefix); pw.print(cursor.getString(TABLE_PERMISSIONS_COL_PACKAGE));
-                        pw.print('/');
-                        final String uuid = cursor.getString(TABLE_PERMISSIONS_COL_VOLUME_UUID);
-                        if (uuid != null) {
-                            pw.print(uuid); pw.print('>');
-                        }
-                        pw.print(cursor.getString(TABLE_PERMISSIONS_COL_DIRECTORY));
-                        pw.print(": "); pw.println(cursor.getInt(TABLE_PERMISSIONS_COL_GRANTED) == 1);
-                    }
-                }
-            }
-        }
-
-        pw.print("Raw permissions: ");
-        final List<Permission> rawPermissions = getAllPermissions(getContext());
-        if (rawPermissions.isEmpty()) {
-            pw.println("N/A");
-        } else {
-            final int size = rawPermissions.size();
-            pw.println(size);
-            for (int i = 0; i < size; i++) {
-                final Permission permission = rawPermissions.get(i);
-                pw.print(prefix); pw.println(permission);
-            }
-        }
-    }
-}
diff --git a/src/com/android/documentsui/SharedInputHandler.java b/src/com/android/documentsui/SharedInputHandler.java
index 0c91341..28eba70 100644
--- a/src/com/android/documentsui/SharedInputHandler.java
+++ b/src/com/android/documentsui/SharedInputHandler.java
@@ -20,12 +20,16 @@
 import android.util.Log;
 import android.view.KeyEvent;
 
+import androidx.recyclerview.selection.SelectionTracker;
+
 import com.android.documentsui.base.Events;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Procedure;
 import com.android.documentsui.dirlist.FocusHandler;
-import com.android.documentsui.selection.SelectionHelper;
 
+/**
+ * Handle common input events.
+ */
 public class SharedInputHandler {
 
     private static final String TAG = "SharedInputHandler";
@@ -34,19 +38,22 @@
     private final Procedure mSearchCanceler;
     private final Procedure mDirPopper;
     private final Features mFeatures;
-    private final SelectionHelper mSelectionMgr;
+    private final SelectionTracker<String> mSelectionMgr;
+    private final DrawerController mDrawer;
 
     public SharedInputHandler(
             FocusHandler focusHandler,
-            SelectionHelper selectionMgr,
+            SelectionTracker<String> selectionMgr,
             Procedure searchCanceler,
             Procedure dirPopper,
-            Features features) {
+            Features features,
+            DrawerController drawer) {
         mFocusManager = focusHandler;
         mSearchCanceler = searchCanceler;
         mSelectionMgr = selectionMgr;
         mDirPopper = dirPopper;
         mFeatures = features;
+        mDrawer = drawer;
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
@@ -99,12 +106,19 @@
     }
 
     private boolean onBack() {
+        if (mDrawer.isPresent() && mDrawer.isOpen()) {
+            mDrawer.setOpen(false);
+            return true;
+        }
+
         if (mSearchCanceler.run()) {
             return true;
         }
 
         if (mSelectionMgr.hasSelection()) {
-            if (DEBUG) Log.d(TAG, "Back pressed. Clearing existing selection.");
+            if (DEBUG) {
+                Log.d(TAG, "Back pressed. Clearing existing selection.");
+            }
             mSelectionMgr.clearSelection();
             return true;
         }
@@ -118,7 +132,9 @@
         }
 
         if (mSelectionMgr.hasSelection()) {
-            if (DEBUG) Log.d(TAG, "ESC pressed. Clearing existing selection.");
+            if (DEBUG) {
+                Log.d(TAG, "ESC pressed. Clearing existing selection.");
+            }
             mSelectionMgr.clearSelection();
             return true;
         }
diff --git a/src/com/android/documentsui/ShortcutsUpdater.java b/src/com/android/documentsui/ShortcutsUpdater.java
index 5fcdf27..7da9371 100644
--- a/src/com/android/documentsui/ShortcutsUpdater.java
+++ b/src/com/android/documentsui/ShortcutsUpdater.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui;
 
-import android.annotation.DrawableRes;
+import androidx.annotation.DrawableRes;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ShortcutInfo;
@@ -25,6 +25,7 @@
 import com.android.documentsui.R;
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.Shared;
 import com.android.documentsui.files.FilesActivity;
 import com.android.documentsui.prefs.ScopedPreferences;
 
@@ -48,6 +49,10 @@
     }
 
     public void update(Collection<RootInfo> roots) {
+        if (!Shared.isLauncherEnabled(mContext)) {
+            return;
+        }
+
         ShortcutManager mgr = mContext.getSystemService(ShortcutManager.class);
 
         Map<String, ShortcutInfo> existing = getPinnedShortcuts(mgr);
@@ -117,7 +122,7 @@
     }
 
     private int getNumDynSlots(ShortcutManager mgr, int numDevices) {
-        int slots = mgr.getMaxShortcutCountForActivity() - mgr.getManifestShortcuts().size();
+        int slots = mgr.getMaxShortcutCountPerActivity() - mgr.getManifestShortcuts().size();
         return numDevices >= slots ? slots : numDevices;
     }
 
diff --git a/src/com/android/documentsui/ThumbnailCache.java b/src/com/android/documentsui/ThumbnailCache.java
index cfa5357..b98ee20 100644
--- a/src/com/android/documentsui/ThumbnailCache.java
+++ b/src/com/android/documentsui/ThumbnailCache.java
@@ -16,15 +16,16 @@
 
 package com.android.documentsui;
 
-import android.annotation.IntDef;
-import android.annotation.Nullable;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import androidx.core.util.Pools;
+
 import android.content.ComponentCallbacks2;
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.net.Uri;
 import android.util.LruCache;
 import android.util.Pair;
-import android.util.Pools;
 
 import com.android.documentsui.base.Shared;
 
diff --git a/src/com/android/documentsui/ThumbnailLoader.java b/src/com/android/documentsui/ThumbnailLoader.java
index f5a93aa..56cadc3 100644
--- a/src/com/android/documentsui/ThumbnailLoader.java
+++ b/src/com/android/documentsui/ThumbnailLoader.java
@@ -15,6 +15,8 @@
  */
 package com.android.documentsui;
 
+import static android.content.ContentResolver.wrap;
+
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
 import android.content.ContentProviderClient;
@@ -25,6 +27,7 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.CancellationSignal;
+import android.os.FileUtils;
 import android.os.OperationCanceledException;
 import android.provider.DocumentsContract;
 import android.util.Log;
@@ -104,7 +107,8 @@
         try {
             client = DocumentsApplication.acquireUnstableProviderOrThrow(
                 resolver, mUri.getAuthority());
-            result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal);
+            result = DocumentsContract.getDocumentThumbnail(wrap(client),
+                    mUri, mThumbSize, mSignal);
             if (result != null && mAddToCache) {
                 final ThumbnailCache cache = DocumentsApplication.getThumbnailCache(context);
                 cache.putThumbnail(mUri, mThumbSize, result, mLastModified);
@@ -114,7 +118,7 @@
                 Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e);
             }
         } finally {
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(client);
         }
         return result;
     }
diff --git a/src/com/android/documentsui/TimeoutTask.java b/src/com/android/documentsui/TimeoutTask.java
index 9e7bbb8..a290bce 100644
--- a/src/com/android/documentsui/TimeoutTask.java
+++ b/src/com/android/documentsui/TimeoutTask.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import android.annotation.CallSuper;
+import androidx.annotation.CallSuper;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.Looper;
diff --git a/src/com/android/documentsui/selection/ViewAutoScroller.java b/src/com/android/documentsui/ViewAutoScroller.java
similarity index 94%
rename from src/com/android/documentsui/selection/ViewAutoScroller.java
rename to src/com/android/documentsui/ViewAutoScroller.java
index b77176c..f7b062e 100644
--- a/src/com/android/documentsui/selection/ViewAutoScroller.java
+++ b/src/com/android/documentsui/ViewAutoScroller.java
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.selection;
+package com.android.documentsui;
 
 import android.graphics.Point;
 
 /**
  * Provides auto-scrolling upon request when user's interaction with the application
- * introduces a natural intent to scroll. Used by BandController, GestureSelector,
- * and DragHoverListener to allow auto scrolling when user either does band selection,
- * attempting to drag and drop files to somewhere off the current screen, or trying to motion select
- * past top/bottom of the screen.
+ * introduces a natural intent to scroll. Used by DragHoverListener to allow auto scrolling
+ * when user either does band selection, attempting to drag and drop files to somewhere off
+ * the current screen, or trying to motion select past top/bottom of the screen.
  */
 public final class ViewAutoScroller implements Runnable {
 
diff --git a/src/com/android/documentsui/archives/Archive.java b/src/com/android/documentsui/archives/Archive.java
index 14d703c..cf7ba2d 100644
--- a/src/com/android/documentsui/archives/Archive.java
+++ b/src/com/android/documentsui/archives/Archive.java
@@ -24,19 +24,16 @@
 import android.net.Uri;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
-import android.os.storage.StorageManager;
-import android.provider.DocumentsContract;
-import android.provider.MetadataReader;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
 import android.text.TextUtils;
 import android.webkit.MimeTypeMap;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Nullable;
+import androidx.core.util.Preconditions;
 
 import java.io.Closeable;
 import java.io.File;
@@ -45,8 +42,9 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.zip.ZipEntry;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 
 /**
  * Provides basic implementation for creating, extracting and accessing
@@ -72,11 +70,11 @@
 
     // The container as well as values are guarded by mEntries.
     @GuardedBy("mEntries")
-    final Map<String, ZipEntry> mEntries;
+    final Map<String, ArchiveEntry> mEntries;
 
     // The container as well as values and elements of values are guarded by mEntries.
     @GuardedBy("mEntries")
-    final Map<String, List<ZipEntry>> mTree;
+    final Map<String, List<ArchiveEntry>> mTree;
 
     Archive(
             Context context,
@@ -95,9 +93,16 @@
     /**
      * Returns a valid, normalized path for an entry.
      */
-    public static String getEntryPath(ZipEntry entry) {
-        Preconditions.checkArgument(entry.isDirectory() == entry.getName().endsWith("/"),
-                "Ill-formated ZIP-file.");
+    public static String getEntryPath(ArchiveEntry entry) {
+        if (entry instanceof ZipArchiveEntry) {
+            /**
+             * Some of archive entry doesn't have the same naming rule.
+             * For example: The name of 7 zip directory entry doesn't end with '/'.
+             * Only check for Zip archive.
+             */
+            Preconditions.checkArgument(entry.isDirectory() == entry.getName().endsWith("/"),
+                    "Ill-formated ZIP-file.");
+        }
         if (entry.getName().startsWith("/")) {
             return entry.getName();
         } else {
@@ -138,11 +143,11 @@
         }
 
         synchronized (mEntries) {
-            final List<ZipEntry> parentList = mTree.get(parsedParentId.mPath);
+            final List<ArchiveEntry> parentList = mTree.get(parsedParentId.mPath);
             if (parentList == null) {
                 throw new FileNotFoundException();
             }
-            for (final ZipEntry entry : parentList) {
+            for (final ArchiveEntry entry : parentList) {
                 addCursorRow(result, entry);
             }
         }
@@ -160,7 +165,7 @@
                 "Mismatching archive Uri. Expected: %s, actual: %s.");
 
         synchronized (mEntries) {
-            final ZipEntry entry = mEntries.get(parsedId.mPath);
+            final ArchiveEntry entry = mEntries.get(parsedId.mPath);
             if (entry == null) {
                 throw new FileNotFoundException();
             }
@@ -181,12 +186,12 @@
                 "Mismatching archive Uri. Expected: %s, actual: %s.");
 
         synchronized (mEntries) {
-            final ZipEntry entry = mEntries.get(parsedId.mPath);
+            final ArchiveEntry entry = mEntries.get(parsedId.mPath);
             if (entry == null) {
                 return false;
             }
 
-            final ZipEntry parentEntry = mEntries.get(parsedParentId.mPath);
+            final ArchiveEntry parentEntry = mEntries.get(parsedParentId.mPath);
             if (parentEntry == null || !parentEntry.isDirectory()) {
                 return false;
             }
@@ -213,7 +218,7 @@
                 "Mismatching archive Uri. Expected: %s, actual: %s.");
 
         synchronized (mEntries) {
-            final ZipEntry entry = mEntries.get(parsedId.mPath);
+            final ArchiveEntry entry = mEntries.get(parsedId.mPath);
             if (entry == null) {
                 throw new FileNotFoundException();
             }
@@ -270,7 +275,7 @@
     /**
      * Not thread safe.
      */
-    void addCursorRow(MatrixCursor cursor, ZipEntry entry) {
+    void addCursorRow(MatrixCursor cursor, ArchiveEntry entry) {
         final MatrixCursor.RowBuilder row = cursor.newRow();
         final ArchiveId parsedId = createArchiveId(getEntryPath(entry));
         row.add(Document.COLUMN_DOCUMENT_ID, parsedId.toDocumentId());
@@ -289,7 +294,7 @@
         row.add(Document.COLUMN_FLAGS, flags);
     }
 
-    static String getMimeTypeForEntry(ZipEntry entry) {
+    static String getMimeTypeForEntry(ArchiveEntry entry) {
         if (entry.isDirectory()) {
             return Document.MIME_TYPE_DIR;
         }
diff --git a/src/com/android/documentsui/archives/ArchiveEntryInputStream.java b/src/com/android/documentsui/archives/ArchiveEntryInputStream.java
new file mode 100644
index 0000000..0b1c0c2
--- /dev/null
+++ b/src/com/android/documentsui/archives/ArchiveEntryInputStream.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2019 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.documentsui.archives;
+
+import android.text.TextUtils;
+
+import androidx.annotation.NonNull;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.sevenz.SevenZFile;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+
+/**
+ * To simulate the input stream by using ZipFile, SevenZFile, or ArchiveInputStream.
+ */
+abstract class ArchiveEntryInputStream extends InputStream {
+    private final long mSize;
+    private final ReadSource mReadSource;
+
+    private ArchiveEntryInputStream(ReadSource readSource, @NonNull ArchiveEntry archiveEntry) {
+        mReadSource = readSource;
+        mSize = archiveEntry.getSize();
+    }
+
+    @Override
+    public int read() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        if (mReadSource != null) {
+            return mReadSource.read(b, off, len);
+        }
+
+        return -1; /* end of input stream */
+    }
+
+    @Override
+    public int available() throws IOException {
+        return mReadSource == null ? 0 : StrictMath.toIntExact(mSize);
+    }
+
+    /**
+     * The interface describe how to make the ArchiveHandle to next entry.
+     */
+    private interface NextEntryIterator {
+        ArchiveEntry getNextEntry() throws IOException;
+    }
+
+    /**
+     * The interface provide where to read the data.
+     */
+    private interface ReadSource {
+        int read(byte[] b, int off, int len) throws IOException;
+    }
+
+    private static boolean moveToArchiveEntry(
+            NextEntryIterator nextEntryIterator, ArchiveEntry archiveEntry) throws IOException {
+        ArchiveEntry entry;
+        while ((entry = nextEntryIterator.getNextEntry()) != null) {
+            if (TextUtils.equals(entry.getName(), archiveEntry.getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static class WrapArchiveInputStream extends ArchiveEntryInputStream {
+        private WrapArchiveInputStream(ReadSource readSource,
+                ArchiveEntry archiveEntry, NextEntryIterator iterator) throws IOException {
+            super(readSource, archiveEntry);
+
+            moveToArchiveEntry(iterator, archiveEntry);
+        }
+    }
+
+    private static class WrapZipFileInputStream extends ArchiveEntryInputStream {
+        private final Closeable mCloseable;
+
+        private WrapZipFileInputStream(
+                ReadSource readSource, @NonNull ArchiveEntry archiveEntry, Closeable closeable)
+                throws IOException {
+            super(readSource, archiveEntry);
+            mCloseable = closeable;
+        }
+
+        @Override
+        public void close() throws IOException {
+            super.close();
+            if (mCloseable != null) {
+                mCloseable.close();
+            }
+        }
+    }
+
+    static InputStream create(@NonNull ArchiveHandle archiveHandle,
+            @NonNull ArchiveEntry archiveEntry) throws IOException {
+        if (archiveHandle == null) {
+            throw new IllegalArgumentException("archiveHandle is null");
+        }
+
+        if (archiveEntry == null) {
+            throw new IllegalArgumentException("ArchiveEntry is empty");
+        }
+
+        if (archiveEntry.isDirectory() || archiveEntry.getSize() <= 0
+                || TextUtils.isEmpty(archiveEntry.getName())) {
+            throw new IllegalArgumentException("ArchiveEntry is an invalid file entry");
+        }
+
+        Object commonArchive = archiveHandle.getCommonArchive();
+
+        if (commonArchive instanceof SevenZFile) {
+            return new WrapArchiveInputStream(
+                (b, off, len) -> ((SevenZFile) commonArchive).read(b, off, len),
+                archiveEntry,
+                () -> ((SevenZFile) commonArchive).getNextEntry());
+        } else if (commonArchive instanceof ZipFile) {
+            final InputStream inputStream =
+                    ((ZipFile) commonArchive).getInputStream((ZipArchiveEntry) archiveEntry);
+            return new WrapZipFileInputStream(
+                (b, off, len) -> inputStream.read(b, off, len),
+                archiveEntry,
+                () -> inputStream.close());
+        } else if (commonArchive instanceof ArchiveInputStream) {
+            return new WrapArchiveInputStream(
+                (b, off, len) -> ((ArchiveInputStream) commonArchive).read(b, off, len),
+                archiveEntry,
+                () -> ((ArchiveInputStream) commonArchive).getNextEntry());
+        }
+
+        return null;
+    }
+}
diff --git a/src/com/android/documentsui/archives/ArchiveHandle.java b/src/com/android/documentsui/archives/ArchiveHandle.java
new file mode 100644
index 0000000..45792a1
--- /dev/null
+++ b/src/com/android/documentsui/archives/ArchiveHandle.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2019 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.documentsui.archives;
+
+import static androidx.core.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkNotNull;
+
+import static com.android.documentsui.archives.ArchiveRegistry.COMMON_ARCHIVE_TYPE;
+import static com.android.documentsui.archives.ArchiveRegistry.SEVEN_Z_TYPE;
+import static com.android.documentsui.archives.ArchiveRegistry.ZIP_TYPE;
+
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.Closeable;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.channels.SeekableByteChannel;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.sevenz.SevenZFile;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.compress.compressors.CompressorStreamFactory;
+
+/**
+ * To handle to all of supported support types of archive or compressed+archive files.
+ * @param <T> the archive class such as SevenZFile, ZipFile, ArchiveInputStream etc.
+ */
+abstract class ArchiveHandle<T> implements Closeable {
+    private static final String TAG = ArchiveHandle.class.getSimpleName();
+    /**
+     * To re-create the CommonArchive that belongs to SevenZFile, ZipFile, or
+     * ArchiveInputStream. It needs file descriptor to create the input stream or seek to the head.
+     */
+    @NonNull
+    private final ParcelFileDescriptor mParcelFileDescriptor;
+
+    /**
+     * To re-create the CommonArchive that belongs to SevenZFile, ZipFile, or
+     * ArchiveInputStream. It needs MIME type to know how to re-create.
+     */
+    @NonNull
+    private final String mMimeType;
+
+    /**
+     * CommonArchive is generic type. It may be SevenZFile, ZipFile, or ArchiveInputStream.
+     */
+    @NonNull
+    private T mCommonArchive;
+
+    /**
+     * To use factory pattern ensure the only one way to create the ArchiveHandle instance.
+     * @param parcelFileDescriptor the file descriptor
+     * @param mimeType the mime type of the file
+     * @param commonArchive the common archive instance
+     */
+    private ArchiveHandle(@NonNull ParcelFileDescriptor parcelFileDescriptor,
+                          @NonNull String mimeType,
+                          @NonNull T commonArchive) {
+        mParcelFileDescriptor = parcelFileDescriptor;
+        mMimeType = mimeType;
+        mCommonArchive = commonArchive;
+    }
+
+    /**
+     * It's used to re-create the file input stream. Just like SevenZFile or ArchiveInputStream.
+     *
+     * @return the file input stream
+     */
+    @NonNull
+    private FileInputStream recreateCommonArchiveStream() throws IOException {
+        FileInputStream fileInputStream =
+                new FileInputStream(mParcelFileDescriptor.getFileDescriptor());
+        SeekableByteChannel seekableByteChannel = fileInputStream.getChannel();
+        seekableByteChannel.position(0);
+        return fileInputStream;
+    }
+
+    /**
+     * To get the MIME type of the file.
+     * @return the MIME type of file
+     */
+    @NonNull
+    protected String getMimeType() {
+        return mMimeType;
+    }
+
+    /**
+     * To get the common archive instance.
+     *
+     * @return the common archive instance.
+     */
+    @NonNull
+    public final T getCommonArchive() {
+        return mCommonArchive;
+    }
+
+    private void setCommonArchive(@NonNull T commonArchive) {
+        mCommonArchive = commonArchive;
+    }
+
+    /**
+     * Neither SevenZFile nor ArchiveInputStream likes ZipFile that has the API
+     * getInputStream(ArchiveEntry), rewind or reset, so it needs to close the
+     * current instance and recreate a new one.
+     *
+     * @param archiveEntry the target entry
+     * @return the input stream related to archiveEntry
+     * @throws IOException invalid file descriptor may raise the IOException
+     * @throws CompressorException invalid compress name may raise the CompressException
+     * @throws ArchiveException invalid Archive name may raise the ArchiveException
+     */
+    protected InputStream getInputStream(@NonNull ArchiveEntry archiveEntry)
+            throws IOException, CompressorException, ArchiveException {
+
+        if (!isCommonArchiveSupportGetInputStream()) {
+            FileInputStream fileInputStream = recreateCommonArchiveStream();
+            T commonArchive = recreateCommonArchive(fileInputStream);
+            if (commonArchive != null) {
+                closeCommonArchive();
+                setCommonArchive(commonArchive);
+            } else {
+                Log.e(TAG, "new SevenZFile or ArchiveInputStream is null");
+                fileInputStream.close();
+            }
+        }
+
+        return ArchiveEntryInputStream.create(this, archiveEntry);
+    }
+
+    boolean isCommonArchiveSupportGetInputStream() {
+        return false;
+    }
+
+    void closeCommonArchive() throws IOException {
+        throw new UnsupportedOperationException("This kind of ArchiveHandle doesn't support");
+    }
+
+    T recreateCommonArchive(FileInputStream fileInputStream)
+            throws CompressorException, ArchiveException, IOException {
+        throw new UnsupportedOperationException("This kind of ArchiveHandle doesn't support");
+    }
+
+    public void close() throws IOException {
+        mParcelFileDescriptor.close();
+    }
+
+    /**
+     * To get the enumeration of all of entries from archive.
+     * @return the enumeration of all of entries from archive
+     * @throws IOException it may raise the IOException when the archiveHandle get the next entry
+     */
+    @NonNull
+    public abstract Enumeration<? extends ArchiveEntry> getEntries() throws IOException;
+
+    private static class SevenZFileHandle extends ArchiveHandle<SevenZFile> {
+        SevenZFileHandle(ParcelFileDescriptor parcelFileDescriptor, String mimeType,
+                         SevenZFile commonArchive) {
+            super(parcelFileDescriptor, mimeType, commonArchive);
+        }
+
+        @Override
+        protected void closeCommonArchive() throws IOException {
+            getCommonArchive().close();
+        }
+
+        @Override
+        protected SevenZFile recreateCommonArchive(@NonNull FileInputStream fileInputStream)
+                throws IOException {
+            return new SevenZFile(fileInputStream.getChannel());
+        }
+
+        @NonNull
+        @Override
+        public Enumeration<? extends ArchiveEntry> getEntries() {
+            if (getCommonArchive().getEntries() == null) {
+                return Collections.emptyEnumeration();
+            }
+
+            return Collections.enumeration(
+                    (Collection<? extends ArchiveEntry>) getCommonArchive().getEntries());
+        }
+    }
+
+    private static class ZipFileHandle extends ArchiveHandle<ZipFile> {
+        ZipFileHandle(ParcelFileDescriptor parcelFileDescriptor, String mimeType,
+                      ZipFile commonArchive) {
+            super(parcelFileDescriptor, mimeType, commonArchive);
+        }
+
+        @Override
+        protected boolean isCommonArchiveSupportGetInputStream() {
+            return true;
+        }
+
+        @NonNull
+        @Override
+        public Enumeration<? extends ArchiveEntry> getEntries() {
+            final Enumeration<ZipArchiveEntry> enumeration = getCommonArchive().getEntries();
+            if (enumeration == null) {
+                return Collections.emptyEnumeration();
+            }
+            return enumeration;
+        }
+    }
+
+    private static class CommonArchiveInputHandle extends ArchiveHandle<ArchiveInputStream> {
+        CommonArchiveInputHandle(ParcelFileDescriptor parcelFileDescriptor,
+                                 String mimeType, ArchiveInputStream commonArchive) {
+            super(parcelFileDescriptor, mimeType, commonArchive);
+        }
+
+        @Override
+        protected void closeCommonArchive() throws IOException {
+            getCommonArchive().close();
+        }
+
+        @Override
+        protected ArchiveInputStream recreateCommonArchive(FileInputStream fileInputStream)
+                throws CompressorException, ArchiveException {
+            return createCommonArchive(fileInputStream, getMimeType());
+        }
+
+        @NonNull
+        @Override
+        public Enumeration<? extends ArchiveEntry> getEntries() throws IOException {
+            final ArchiveInputStream archiveInputStream = getCommonArchive();
+            final List<ArchiveEntry> list = new ArrayList<>();
+            ArchiveEntry entry;
+            while ((entry = archiveInputStream.getNextEntry()) != null) {
+                list.add(entry);
+            }
+
+            return Collections.enumeration(list);
+        }
+    }
+
+    @NonNull
+    private static ArchiveInputStream createCommonArchive(
+            @NonNull FileInputStream fileInputStream,
+            @NonNull String mimeType) throws CompressorException, ArchiveException {
+        InputStream inputStream = fileInputStream;
+
+        String compressName = ArchiveRegistry.getCompressName(mimeType);
+        if (!TextUtils.isEmpty(compressName)) {
+            CompressorStreamFactory compressorStreamFactory =
+                    new CompressorStreamFactory();
+            inputStream = compressorStreamFactory
+                    .createCompressorInputStream(compressName, inputStream);
+        }
+
+        ArchiveStreamFactory archiveStreamFactory = new ArchiveStreamFactory();
+        String archiveName = ArchiveRegistry.getArchiveName(mimeType);
+        if (TextUtils.isEmpty(archiveName)) {
+            throw new ArchiveException("Invalid archive name.");
+        }
+
+        return archiveStreamFactory
+                .createArchiveInputStream(archiveName, inputStream);
+    }
+
+    /**
+     * The only one way creates the instance of ArchiveHandle.
+     */
+    public static ArchiveHandle create(@NonNull ParcelFileDescriptor parcelFileDescriptor,
+            @NonNull String mimeType) throws CompressorException, ArchiveException, IOException {
+        checkNotNull(parcelFileDescriptor);
+        checkArgument(!TextUtils.isEmpty(mimeType));
+
+        Integer archiveType = ArchiveRegistry.getArchiveType(mimeType);
+        if (archiveType == null) {
+            throw new UnsupportedOperationException("Doesn't support MIME type " + mimeType);
+        }
+
+        FileInputStream fileInputStream =
+                new FileInputStream(parcelFileDescriptor.getFileDescriptor());
+
+        switch (archiveType) {
+            case COMMON_ARCHIVE_TYPE:
+                ArchiveInputStream archiveInputStream =
+                        createCommonArchive(fileInputStream, mimeType);
+                return new CommonArchiveInputHandle(parcelFileDescriptor, mimeType,
+                        archiveInputStream);
+            case ZIP_TYPE:
+                SeekableByteChannel zipFileChannel = fileInputStream.getChannel();
+                try {
+                    ZipFile zipFile = new ZipFile(zipFileChannel);
+                    return new ZipFileHandle(parcelFileDescriptor, mimeType,
+                            zipFile);
+                } catch (Exception e) {
+                    FileUtils.closeQuietly(zipFileChannel);
+                    throw e;
+                }
+            case SEVEN_Z_TYPE:
+                SeekableByteChannel sevenZFileChannel = fileInputStream.getChannel();
+                try {
+                    SevenZFile sevenZFile = new SevenZFile(sevenZFileChannel);
+                    return new SevenZFileHandle(parcelFileDescriptor, mimeType,
+                            sevenZFile);
+                } catch (Exception e) {
+                    FileUtils.closeQuietly(sevenZFileChannel);
+                    throw e;
+                }
+            default:
+                throw new UnsupportedOperationException("Doesn't support MIME type "
+                        + mimeType);
+        }
+    }
+}
diff --git a/src/com/android/documentsui/archives/ArchiveRegistry.java b/src/com/android/documentsui/archives/ArchiveRegistry.java
new file mode 100644
index 0000000..91e0e20
--- /dev/null
+++ b/src/com/android/documentsui/archives/ArchiveRegistry.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019 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.documentsui.archives;
+
+import static org.apache.commons.compress.archivers.ArchiveStreamFactory.TAR;
+import static org.apache.commons.compress.compressors.CompressorStreamFactory.BROTLI;
+import static org.apache.commons.compress.compressors.CompressorStreamFactory.BZIP2;
+import static org.apache.commons.compress.compressors.CompressorStreamFactory.GZIP;
+import static org.apache.commons.compress.compressors.CompressorStreamFactory.XZ;
+
+import androidx.annotation.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.compress.compressors.brotli.BrotliUtils;
+import org.apache.commons.compress.compressors.xz.XZUtils;
+
+/**
+ * To query how to generate ArchiveHandle, how to create CompressInputStream and how to create
+ * ArchiveInputStream by using MIME type in ArchiveRegistry.
+ */
+final class ArchiveRegistry {
+    static final int COMMON_ARCHIVE_TYPE = 1;
+    static final int ZIP_TYPE = 2;
+    static final int SEVEN_Z_TYPE = 3;
+
+    /**
+     * The mapping between MIME type and how to create ArchiveHandle instance.
+     * key - MIME type
+     * value - the integer value used in ArchiveHandle.create
+     */
+    private static final Map<String, Integer> sHandleArchiveMap = new HashMap<>();
+
+    /**
+     * The mapping between MIME type and the archive name that is used by ArchiveStreamFactory.
+     * key - MIME type
+     * value - the archive name is used as the 1st parameter of ArchiveStreamFactory
+     *                 .createArchiveInputStream
+     */
+    private static final Map<String, String> sMimeTypeArchiveNameMap = new HashMap<>();
+
+    /**
+     * The mapping between MIME type and the compress name that is used by CompressorStreamFactory.
+     * key - MIME type
+     * value - the compress name is used as the 1st parameter of CompressorStreamFactory
+     *                 .createCompressorInputStream
+     */
+    private static final Map<String, String> sMimeTypeCompressNameMap = new HashMap<>();
+
+    static {
+        /* initial sHandleArchiveMap */
+        sHandleArchiveMap.put("application/zip", ZIP_TYPE);
+        sHandleArchiveMap.put("application/x-zip", ZIP_TYPE);
+        sHandleArchiveMap.put("application/x-zip-compressed", ZIP_TYPE);
+        sHandleArchiveMap.put("application/x-7z-compressed", SEVEN_Z_TYPE);
+        sHandleArchiveMap.put("application/x-gtar", COMMON_ARCHIVE_TYPE);
+        sHandleArchiveMap.put("application/x-tar", COMMON_ARCHIVE_TYPE);
+        sHandleArchiveMap.put("application/x-compressed-tar", COMMON_ARCHIVE_TYPE);
+        sHandleArchiveMap.put("application/x-gtar-compressed", COMMON_ARCHIVE_TYPE);
+        sHandleArchiveMap.put("application/x-bzip-compressed-tar", COMMON_ARCHIVE_TYPE);
+        if (BrotliUtils.isBrotliCompressionAvailable()) {
+            sHandleArchiveMap.put("application/x-brotli-compressed-tar", COMMON_ARCHIVE_TYPE);
+        }
+        if (XZUtils.isXZCompressionAvailable()) {
+            sHandleArchiveMap.put("application/x-xz-compressed-tar", COMMON_ARCHIVE_TYPE);
+        }
+
+        /* initial sMimeTypeArchiveNameMap */
+        sMimeTypeArchiveNameMap.put("application/x-gtar", TAR);
+        sMimeTypeArchiveNameMap.put("application/x-tar", TAR);
+        sMimeTypeArchiveNameMap.put("application/x-compressed-tar", TAR);
+        sMimeTypeArchiveNameMap.put("application/x-gtar-compressed", TAR);
+        sMimeTypeArchiveNameMap.put("application/x-bzip-compressed-tar", TAR);
+        sMimeTypeArchiveNameMap.put("application/x-brotli-compressed-tar", TAR);
+        sMimeTypeArchiveNameMap.put("application/x-xz-compressed-tar", TAR);
+
+        /* initial sMimeTypeCompressNameMap */
+        sMimeTypeCompressNameMap.put("application/x-compressed-tar", GZIP);
+        sMimeTypeCompressNameMap.put("application/x-gtar-compressed", GZIP);
+        sMimeTypeCompressNameMap.put("application/x-bzip-compressed-tar", BZIP2);
+        if (BrotliUtils.isBrotliCompressionAvailable()) {
+            sMimeTypeCompressNameMap.put("application/x-brotli-compressed-tar", BROTLI);
+        }
+        if (XZUtils.isXZCompressionAvailable()) {
+            sMimeTypeCompressNameMap.put("application/x-xz-compressed-tar", XZ);
+        }
+    }
+
+    /**
+     * To query the archive name by passing MIME type is used by
+     * ArchiveStreamFactory.createArchiveInputStream.
+     *
+     * @param mimeType the MIME type of the archive file
+     * @return the archive name to tell ArchiveStreamFactory how to extract archive
+     */
+    @Nullable
+    static String getArchiveName(String mimeType) {
+        return sMimeTypeArchiveNameMap.get(mimeType);
+    }
+
+    /**
+     * To query the compress name by passing MIME type is used by
+     * CompressorStreamFactory.createCompressorInputStream.
+     *
+     * @param mimeType the MIME type of the compressed file
+     * @return the compress name to tell CompressorStreamFactory how to uncompress
+     */
+    @Nullable
+    static String getCompressName(String mimeType) {
+        return sMimeTypeCompressNameMap.get(mimeType);
+    }
+
+    /**
+     * To query the method to uncompress the compressed file by MIME type.
+     *
+     * @param mimeType the MIME type of the compressed file
+     * @return the method describe how to uncompress the compressed file
+     */
+    @Nullable
+    static Integer getArchiveType(String mimeType) {
+        return sHandleArchiveMap.get(mimeType);
+    }
+
+    static Set<String> getSupportList() {
+        return sHandleArchiveMap.keySet();
+    }
+}
diff --git a/src/com/android/documentsui/archives/ArchivesProvider.java b/src/com/android/documentsui/archives/ArchivesProvider.java
index 508a1aa..826f4c5 100644
--- a/src/com/android/documentsui/archives/ArchivesProvider.java
+++ b/src/com/android/documentsui/archives/ArchivesProvider.java
@@ -30,14 +30,13 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsProvider;
-import android.provider.MetadataReader;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.util.Log;
 
 import com.android.documentsui.R;
-import com.android.internal.annotations.GuardedBy;
+import androidx.annotation.GuardedBy;
 
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -45,6 +44,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Provides basic implementation for creating, extracting and accessing
@@ -62,9 +62,7 @@
     private static final String TAG = "ArchivesProvider";
     private static final String METHOD_ACQUIRE_ARCHIVE = "acquireArchive";
     private static final String METHOD_RELEASE_ARCHIVE = "releaseArchive";
-    private static final String[] ZIP_MIME_TYPES = {
-            "application/zip", "application/x-zip", "application/x-zip-compressed"
-    };
+    private static final Set<String> ZIP_MIME_TYPES = ArchiveRegistry.getSupportList();
 
     @GuardedBy("mArchives")
     private final Map<Key, Loader> mArchives = new HashMap<>();
@@ -170,7 +168,7 @@
             Log.e(TAG, "An error occurred retrieving the metadata.", e);
             return null;
         } finally {
-            IoUtils.closeQuietly(stream);
+            FileUtils.closeQuietly(stream);
         }
     }
 
diff --git a/src/com/android/documentsui/archives/Loader.java b/src/com/android/documentsui/archives/Loader.java
index ebf63ac..5536e37 100644
--- a/src/com/android/documentsui/archives/Loader.java
+++ b/src/com/android/documentsui/archives/Loader.java
@@ -16,18 +16,19 @@
 
 package com.android.documentsui.archives;
 
-import com.android.internal.annotations.GuardedBy;
-
+import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
 import android.util.Log;
 
-import java.io.File;
-import java.io.FileNotFoundException;
+import androidx.annotation.GuardedBy;
+
 import java.io.IOException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.locks.Lock;
+
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.compressors.CompressorException;
 
 /**
  * Loads an instance of Archive lazily.
@@ -79,11 +80,13 @@
 
         try {
             if (ReadableArchive.supportsAccessMode(mAccessMode)) {
+                final ContentResolver contentResolver = mContext.getContentResolver();
+                final String archiveMimeType = contentResolver.getType(mArchiveUri);
                 mArchive = ReadableArchive.createForParcelFileDescriptor(
                         mContext,
-                        mContext.getContentResolver().openFileDescriptor(
+                        contentResolver.openFileDescriptor(
                                 mArchiveUri, "r", null /* signal */),
-                        mArchiveUri, mAccessMode, mNotificationUri);
+                        mArchiveUri, archiveMimeType, mAccessMode, mNotificationUri);
             } else if (WriteableArchive.supportsAccessMode(mAccessMode)) {
                 mArchive = WriteableArchive.createForParcelFileDescriptor(
                         mContext,
@@ -101,7 +104,7 @@
                     mStatus = STATUS_OPENED;
                 }
             }
-        } catch (IOException | RuntimeException e) {
+        } catch (IOException | RuntimeException | ArchiveException | CompressorException e) {
             Log.e(TAG, "Failed to open the archive.", e);
             synchronized (mLock) {
                 mStatus = STATUS_FAILED;
diff --git a/src/com/android/documentsui/archives/MetadataReader.java b/src/com/android/documentsui/archives/MetadataReader.java
new file mode 100644
index 0000000..93f0da7
--- /dev/null
+++ b/src/com/android/documentsui/archives/MetadataReader.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2018 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.documentsui.archives;
+
+import android.media.ExifInterface;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+
+import androidx.annotation.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class providing support for extracting metadata from a file as a
+ * {@link Bundle} suitable for use with {@link DocumentsContract#getDocumentMetadata}.
+ * <p>Currently only EXIF data is supported.
+ * <p>TODO: Add support for common video and audio types, as well as PDF files.
+ * Copied from android.provider.MetadataReader.java
+ */
+public final class MetadataReader {
+
+    private MetadataReader() {}
+
+    private static final String[] DEFAULT_EXIF_TAGS = {
+            ExifInterface.TAG_APERTURE,
+            ExifInterface.TAG_COPYRIGHT,
+            ExifInterface.TAG_DATETIME,
+            ExifInterface.TAG_EXPOSURE_TIME,
+            ExifInterface.TAG_FOCAL_LENGTH,
+            ExifInterface.TAG_F_NUMBER,
+            ExifInterface.TAG_GPS_LATITUDE,
+            ExifInterface.TAG_GPS_LATITUDE_REF,
+            ExifInterface.TAG_GPS_LONGITUDE,
+            ExifInterface.TAG_GPS_LONGITUDE_REF,
+            ExifInterface.TAG_IMAGE_LENGTH,
+            ExifInterface.TAG_IMAGE_WIDTH,
+            ExifInterface.TAG_ISO_SPEED_RATINGS,
+            ExifInterface.TAG_MAKE,
+            ExifInterface.TAG_MODEL,
+            ExifInterface.TAG_ORIENTATION,
+            ExifInterface.TAG_SHUTTER_SPEED_VALUE,
+    };
+
+    private static final int TYPE_INT = 0;
+    private static final int TYPE_DOUBLE = 1;
+    private static final int TYPE_STRING = 2;
+
+    private static final Map<String, Integer> TYPE_MAPPING = new HashMap<>();
+    static {
+        // TODO: Move this over to ExifInterface.java
+        // Since each ExifInterface item has a type, and there's currently no way to get the type
+        // from the tag, here we identify the tag to the type so that we can call the correct
+        // ExifInterface method
+        TYPE_MAPPING.put(ExifInterface.TAG_ARTIST, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_BITS_PER_SAMPLE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_COMPRESSION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_COPYRIGHT, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_DATETIME, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_IMAGE_DESCRIPTION, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_IMAGE_LENGTH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_IMAGE_WIDTH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_MAKE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_MODEL, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_ORIENTATION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_PLANAR_CONFIGURATION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_PRIMARY_CHROMATICITIES, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_REFERENCE_BLACK_WHITE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_RESOLUTION_UNIT, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_ROWS_PER_STRIP, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SAMPLES_PER_PIXEL, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SOFTWARE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_STRIP_BYTE_COUNTS, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_STRIP_OFFSETS, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_TRANSFER_FUNCTION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_WHITE_POINT, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_X_RESOLUTION, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_Y_CB_CR_COEFFICIENTS, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_Y_CB_CR_POSITIONING, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_Y_RESOLUTION, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_APERTURE_VALUE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_BRIGHTNESS_VALUE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_CFA_PATTERN, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_COLOR_SPACE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_COMPONENTS_CONFIGURATION, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_CONTRAST, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_CUSTOM_RENDERED, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_DATETIME_DIGITIZED, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_DATETIME_ORIGINAL, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_DIGITAL_ZOOM_RATIO, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_EXIF_VERSION, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_EXPOSURE_BIAS_VALUE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_EXPOSURE_INDEX, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_EXPOSURE_MODE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_EXPOSURE_PROGRAM, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_EXPOSURE_TIME, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_F_NUMBER, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_FILE_SOURCE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_FLASH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_FLASH_ENERGY, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_FLASHPIX_VERSION, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_FOCAL_LENGTH, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GAIN_CONTROL, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_ISO_SPEED_RATINGS, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_IMAGE_UNIQUE_ID, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_LIGHT_SOURCE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_MAKER_NOTE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_MAX_APERTURE_VALUE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_METERING_MODE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_NEW_SUBFILE_TYPE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_OECF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_PIXEL_X_DIMENSION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_PIXEL_Y_DIMENSION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_RELATED_SOUND_FILE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SATURATION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SCENE_CAPTURE_TYPE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SCENE_TYPE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SENSING_METHOD, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SHARPNESS, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SHUTTER_SPEED_VALUE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SPECTRAL_SENSITIVITY, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBFILE_TYPE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBSEC_TIME, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBSEC_TIME_DIGITIZED, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBJECT_AREA, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBJECT_DISTANCE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBJECT_DISTANCE_RANGE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_SUBJECT_LOCATION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_USER_COMMENT, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_WHITE_BALANCE, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_ALTITUDE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_ALTITUDE_REF, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_AREA_INFORMATION, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DOP, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DATESTAMP, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_BEARING, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_BEARING_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_DISTANCE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_DISTANCE_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_LATITUDE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_LATITUDE_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_LONGITUDE, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DEST_LONGITUDE_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_DIFFERENTIAL, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_IMG_DIRECTION, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_IMG_DIRECTION_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_LATITUDE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_LATITUDE_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_LONGITUDE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_LONGITUDE_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_MAP_DATUM, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_MEASURE_MODE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_PROCESSING_METHOD, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_SATELLITES, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_SPEED, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_SPEED_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_STATUS, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_TIMESTAMP, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_TRACK, TYPE_DOUBLE);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_TRACK_REF, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_GPS_VERSION_ID, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_INTEROPERABILITY_INDEX, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_THUMBNAIL_IMAGE_LENGTH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_THUMBNAIL_IMAGE_WIDTH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_DNG_VERSION, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_DEFAULT_CROP_SIZE, TYPE_INT);
+        //I don't know how to represent this. Type is unknown
+        //TYPE_MAPPING.put(ExifInterface.TAG_ORF_THUMBNAIL_IMAGE, TYPE_STRING);
+        TYPE_MAPPING.put(ExifInterface.TAG_ORF_PREVIEW_IMAGE_START, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_ORF_PREVIEW_IMAGE_LENGTH, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_ORF_ASPECT_FRAME, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_RW2_SENSOR_BOTTOM_BORDER, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_RW2_SENSOR_LEFT_BORDER, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_RW2_SENSOR_RIGHT_BORDER, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_RW2_SENSOR_TOP_BORDER, TYPE_INT);
+        TYPE_MAPPING.put(ExifInterface.TAG_RW2_ISO, TYPE_INT);
+    }
+    private static final String JPG_MIME_TYPE = "image/jpg";
+    private static final String JPEG_MIME_TYPE = "image/jpeg";
+
+
+    /**
+     * Returns true if caller can generally expect to get metadata results
+     * for the supplied mimetype.
+     */
+    public static boolean isSupportedMimeType(String mimeType) {
+        return JPG_MIME_TYPE.equals(mimeType) || JPEG_MIME_TYPE.equals(mimeType);
+    }
+
+    /**
+     * Generic metadata retrieval method that can retrieve any available metadata from a given doc
+     * Currently only functions for exifdata
+     *
+     * @param metadata the bundle to which we add any relevant metadata
+     * @param stream InputStream containing a file
+     * @param mimeType type of the given file
+     * @param tags a variable amount of keys to differentiate which tags the user wants
+     *             if null, returns a default set of data. See {@link DEFAULT_EXIF_TAGS}.
+     * @throws IOException when the file doesn't exist
+     */
+    public static void getMetadata(Bundle metadata, InputStream stream, String mimeType,
+            @Nullable String[] tags) throws IOException {
+        List<String> metadataTypes = new ArrayList<>();
+        if (isSupportedMimeType(mimeType)) {
+            Bundle exifData = getExifData(stream, tags);
+            if (exifData.size() > 0) {
+                metadata.putBundle(DocumentsContract.METADATA_EXIF, exifData);
+                metadataTypes.add(DocumentsContract.METADATA_EXIF);
+            }
+        }
+        metadata.putStringArray(DocumentsContract.METADATA_TYPES,
+                metadataTypes.toArray(new String[metadataTypes.size()]));
+        // TODO: Add support for PDF and Video metadata
+        // TODO: Broaden image support to all images
+    }
+
+    /**
+     * Helper method that is called if getMetadata is called for an image mimeType.
+     *
+     * @param stream the input stream from which to extra data.
+     * @param tags a list of ExifInterface tags that are used to retrieve data.
+     *             if null, returns a default set of data. See {@link DEFAULT_EXIF_TAGS}.
+     */
+    private static Bundle getExifData(InputStream stream, @Nullable String[] tags)
+            throws IOException {
+        if (tags == null) {
+            tags = DEFAULT_EXIF_TAGS;
+        }
+
+        ExifInterface exifInterface = new ExifInterface(stream);
+        Bundle exif = new Bundle();
+        for (String tag : tags) {
+            if (TYPE_MAPPING.get(tag).equals(TYPE_INT)) {
+                int data = exifInterface.getAttributeInt(tag, Integer.MIN_VALUE);
+                if (data != Integer.MIN_VALUE) {
+                    exif.putInt(tag, data);
+                }
+            } else if (TYPE_MAPPING.get(tag).equals(TYPE_DOUBLE)) {
+                double data = exifInterface.getAttributeDouble(tag, Double.MIN_VALUE);
+                if (data != Double.MIN_VALUE) {
+                    exif.putDouble(tag, data);
+                }
+            } else if (TYPE_MAPPING.get(tag).equals(TYPE_STRING)) {
+                String data = exifInterface.getAttribute(tag);
+                if (data != null) {
+                    exif.putString(tag, data);
+                }
+            }
+        }
+        return exif;
+    }
+}
diff --git a/src/com/android/documentsui/archives/Proxy.java b/src/com/android/documentsui/archives/Proxy.java
index a2336b7..c8bfab0 100644
--- a/src/com/android/documentsui/archives/Proxy.java
+++ b/src/com/android/documentsui/archives/Proxy.java
@@ -16,28 +16,29 @@
 
 package com.android.documentsui.archives;
 
+import android.os.FileUtils;
 import android.os.ProxyFileDescriptorCallback;
 import android.system.ErrnoException;
 import android.system.OsConstants;
-import android.util.Log;
-import android.util.jar.StrictJarFile;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.zip.ZipEntry;
 
-import libcore.io.IoUtils;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.compressors.CompressorException;
 
 /**
  * Provides a backend for a seekable file descriptors for files in archives.
  */
 public class Proxy extends ProxyFileDescriptorCallback {
-    private final StrictJarFile mFile;
-    private final ZipEntry mEntry;
+    private final ArchiveHandle mFile;
+    private final ArchiveEntry mEntry;
     private InputStream mInputStream = null;
     private long mOffset = 0;
 
-    Proxy(StrictJarFile file, ZipEntry entry) throws IOException {
+    Proxy(ArchiveHandle file, ArchiveEntry entry)
+            throws IOException, CompressorException, ArchiveException {
         mFile = file;
         mEntry = entry;
         recreateInputStream();
@@ -56,6 +57,12 @@
                 recreateInputStream();
             } catch (IOException e) {
                 throw new ErrnoException("onRead", OsConstants.EIO);
+            } catch (ArchiveException e) {
+                throw new ErrnoException("onRead archive exception. " + e.getMessage(),
+                        OsConstants.EIO);
+            } catch (CompressorException e) {
+                throw new ErrnoException("onRead uncompress exception. " + e.getMessage(),
+                        OsConstants.EIO);
             }
         }
 
@@ -82,14 +89,15 @@
         }
 
         return size - remainingSize;
-   }
-
-    @Override public void onRelease() {
-        IoUtils.closeQuietly(mInputStream);
     }
 
-    private void recreateInputStream() throws IOException {
-        IoUtils.closeQuietly(mInputStream);
+    @Override public void onRelease() {
+        FileUtils.closeQuietly(mInputStream);
+    }
+
+    private void recreateInputStream()
+            throws IOException, CompressorException, ArchiveException {
+        FileUtils.closeQuietly(mInputStream);
         mInputStream = mFile.getInputStream(mEntry);
         mOffset = 0;
     }
diff --git a/src/com/android/documentsui/archives/ReadableArchive.java b/src/com/android/documentsui/archives/ReadableArchive.java
index 66ea069..302f582 100644
--- a/src/com/android/documentsui/archives/ReadableArchive.java
+++ b/src/com/android/documentsui/archives/ReadableArchive.java
@@ -16,6 +16,10 @@
 
 package com.android.documentsui.archives;
 
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
+
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.graphics.Point;
@@ -23,33 +27,33 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
-import android.os.OperationCanceledException;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.StorageManager;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
 import android.util.Log;
-import android.util.jar.StrictJarFile;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.util.Preconditions;
 
-import libcore.io.IoUtils;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.apache.commons.compress.utils.IOUtils;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.Date;
+import java.util.Enumeration;
 import java.util.List;
-import java.util.Set;
 import java.util.Stack;
-import java.util.concurrent.TimeUnit;
-import java.util.zip.ZipEntry;
 
 /**
  * Provides basic implementation for extracting and accessing
@@ -61,16 +65,19 @@
     private static final String TAG = "ReadableArchive";
 
     private final StorageManager mStorageManager;
-    private final StrictJarFile mZipFile;
+    private final ArchiveHandle mArchiveHandle;
+    private final ParcelFileDescriptor mParcelFileDescriptor;
+    private final Handler mHandler;
+    private HandlerThread mHandlerThread;
 
     private ReadableArchive(
             Context context,
-            @Nullable File file,
-            @Nullable FileDescriptor fd,
+            @Nullable ParcelFileDescriptor parcelFileDescriptor,
             Uri archiveUri,
+            String archiveMimeType,
             int accessMode,
             @Nullable Uri notificationUri)
-            throws IOException {
+            throws IOException, CompressorException, ArchiveException {
         super(context, archiveUri, accessMode, notificationUri);
         if (!supportsAccessMode(accessMode)) {
             throw new IllegalStateException("Unsupported access mode.");
@@ -78,20 +85,24 @@
 
         mStorageManager = mContext.getSystemService(StorageManager.class);
 
-        mZipFile = file != null ?
-                new StrictJarFile(file.getPath(), false /* verify */,
-                        false /* signatures */) :
-                new StrictJarFile(fd, false /* verify */, false /* signatures */);
+        if (parcelFileDescriptor == null || parcelFileDescriptor.getFileDescriptor() == null) {
+            throw new IllegalArgumentException("File descriptor is invalid");
+        }
+        mParcelFileDescriptor = parcelFileDescriptor;
 
-        ZipEntry entry;
+        mArchiveHandle = ArchiveHandle.create(parcelFileDescriptor, archiveMimeType);
+
+        ArchiveEntry entry;
         String entryPath;
-        final Iterator<ZipEntry> it = mZipFile.iterator();
-        final Stack<ZipEntry> stack = new Stack<>();
-        while (it.hasNext()) {
-            entry = it.next();
+        final Enumeration<ArchiveEntry> it = mArchiveHandle.getEntries();
+        final Stack<ArchiveEntry> stack = new Stack<>();
+        while (it.hasMoreElements()) {
+            entry = it.nextElement();
             if (entry.isDirectory() != entry.getName().endsWith("/")) {
-                throw new IOException(
-                        "Directories must have a trailing slash, and files must not.");
+                if (DEBUG) {
+                    Log.d(TAG, "directory entry doesn't end with /");
+                }
+                continue;
             }
             entryPath = getEntryPath(entry);
             if (mEntries.containsKey(entryPath)) {
@@ -99,7 +110,7 @@
             }
             mEntries.put(entryPath, entry);
             if (entry.isDirectory()) {
-                mTree.put(entryPath, new ArrayList<ZipEntry>());
+                mTree.put(entryPath, new ArrayList<ArchiveEntry>());
             }
             if (!"/".equals(entryPath)) { // Skip root, as it doesn't have a parent.
                 stack.push(entry);
@@ -108,8 +119,8 @@
 
         int delimiterIndex;
         String parentPath;
-        ZipEntry parentEntry;
-        List<ZipEntry> parentList;
+        ArchiveEntry parentEntry;
+        List<ArchiveEntry> parentList;
 
         // Go through all directories recursively and build a tree structure.
         while (stack.size() > 0) {
@@ -123,12 +134,32 @@
             parentList = mTree.get(parentPath);
 
             if (parentList == null) {
-                // The ZIP file doesn't contain all directories leading to the entry.
-                // It's rare, but can happen in a valid ZIP archive. In such case create a
-                // fake ZipEntry and add it on top of the stack to process it next.
-                parentEntry = new ZipEntry(parentPath);
-                parentEntry.setSize(0);
-                parentEntry.setTime(entry.getTime());
+                // The archive file doesn't contain all directories leading to the entry.
+                // It's rare, but can happen in a valid archive. In such case create a
+                // fake ArchiveEntry and add it on top of the stack to process it next.
+                final String newParentPath = parentPath;
+                final Date newParentLastModify = entry.getLastModifiedDate();
+                parentEntry = new ArchiveEntry() {
+                    @Override
+                    public String getName() {
+                        return newParentPath;
+                    }
+
+                    @Override
+                    public long getSize() {
+                        return 0;
+                    }
+
+                    @Override
+                    public boolean isDirectory() {
+                        return true;
+                    }
+
+                    @Override
+                    public Date getLastModifiedDate() {
+                        return newParentLastModify;
+                    }
+                };
                 mEntries.put(parentPath, parentEntry);
 
                 if (!"/".equals(parentPath)) {
@@ -141,43 +172,47 @@
 
             parentList.add(entry);
         }
+
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
     }
 
     /**
+     * To check the access mode is readable.
+     *
      * @see ParcelFileDescriptor
      */
     public static boolean supportsAccessMode(int accessMode) {
-        return accessMode == ParcelFileDescriptor.MODE_READ_ONLY;
+        return accessMode == MODE_READ_ONLY;
     }
 
     /**
      * Creates a DocumentsArchive instance for opening, browsing and accessing
      * documents within the archive passed as a file descriptor.
-     *
+     * <p>
      * If the file descriptor is not seekable, then a snapshot will be created.
-     *
+     * </p><p>
      * This method takes ownership for the passed descriptor. The caller must
      * not use it after passing.
-     *
+     * </p>
      * @param context Context of the provider.
      * @param descriptor File descriptor for the archive's contents.
      * @param archiveUri Uri of the archive document.
      * @param accessMode Access mode for the archive {@see ParcelFileDescriptor}.
-     * @param Uri notificationUri Uri for notifying that the archive file has changed.
+     * @param notificationUri notificationUri Uri for notifying that the archive file has changed.
      */
     public static ReadableArchive createForParcelFileDescriptor(
-            Context context, ParcelFileDescriptor descriptor, Uri archiveUri, int accessMode,
-            @Nullable Uri notificationUri)
-            throws IOException {
-        FileDescriptor fd = null;
-        try {
-            if (canSeek(descriptor)) {
-                fd = new FileDescriptor();
-                fd.setInt$(descriptor.detachFd());
-                return new ReadableArchive(context, null, fd, archiveUri, accessMode,
-                        notificationUri);
-            }
+            Context context, ParcelFileDescriptor descriptor, Uri archiveUri,
+            @NonNull String archiveMimeType, int accessMode, @Nullable Uri notificationUri)
+            throws IOException, CompressorException, ArchiveException {
+        if (canSeek(descriptor)) {
+            return new ReadableArchive(context, descriptor,
+                    archiveUri, archiveMimeType, accessMode,
+                    notificationUri);
+        }
 
+        try {
             // Fallback for non-seekable file descriptors.
             File snapshotFile = null;
             try {
@@ -202,7 +237,12 @@
                     }
                     outputStream.flush();
                 }
-                return new ReadableArchive(context, snapshotFile, null, archiveUri, accessMode,
+
+                ParcelFileDescriptor snapshotPfd = ParcelFileDescriptor.open(
+                        snapshotFile, MODE_READ_ONLY);
+
+                return new ReadableArchive(context, snapshotPfd,
+                        archiveUri, archiveMimeType, accessMode,
                         notificationUri);
             } finally {
                 // On UNIX the file will be still available for processes which opened it, even
@@ -214,8 +254,7 @@
         } catch (Exception e) {
             // Since the method takes ownership of the passed descriptor, close it
             // on exception.
-            IoUtils.closeQuietly(descriptor);
-            IoUtils.closeQuietly(fd);
+            FileUtils.closeQuietly(descriptor);
             throw e;
         }
     }
@@ -230,16 +269,20 @@
         MorePreconditions.checkArgumentEquals(mArchiveUri, parsedId.mArchiveUri,
                 "Mismatching archive Uri. Expected: %s, actual: %s.");
 
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
+        final ArchiveEntry entry = mEntries.get(parsedId.mPath);
         if (entry == null) {
             throw new FileNotFoundException();
         }
 
         try {
-            return mStorageManager.openProxyFileDescriptor(
-                    ParcelFileDescriptor.MODE_READ_ONLY, new Proxy(mZipFile, entry));
+            return mStorageManager.openProxyFileDescriptor(MODE_READ_ONLY,
+                    new Proxy(mArchiveHandle, entry), mHandler);
         } catch (IOException e) {
             throw new IllegalStateException(e);
+        } catch (ArchiveException e) {
+            throw new IllegalStateException(e);
+        } catch (CompressorException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -253,14 +296,14 @@
         Preconditions.checkArgument(getDocumentType(documentId).startsWith("image/"),
                 "Thumbnails only supported for image/* MIME type.");
 
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
+        final ArchiveEntry entry = mEntries.get(parsedId.mPath);
         if (entry == null) {
             throw new FileNotFoundException();
         }
 
         InputStream inputStream = null;
         try {
-            inputStream = mZipFile.getInputStream(entry);
+            inputStream = mArchiveHandle.getInputStream(entry);
             final ExifInterface exif = new ExifInterface(inputStream);
             if (exif.hasThumbnail()) {
                 Bundle extras = null;
@@ -285,8 +328,12 @@
         } catch (IOException e) {
             // Ignore the exception, as reading the EXIF may legally fail.
             Log.e(TAG, "Failed to obtain thumbnail from EXIF.", e);
+        } catch (ArchiveException e) {
+            Log.e(TAG, "Failed to open archive.", e);
+        } catch (CompressorException e) {
+            Log.e(TAG, "Failed to uncompress.", e);
         } finally {
-            IoUtils.closeQuietly(inputStream);
+            FileUtils.closeQuietly(inputStream);
         }
 
         return new AssetFileDescriptor(
@@ -302,9 +349,20 @@
     @Override
     public void close() {
         try {
-            mZipFile.close();
+            mArchiveHandle.close();
         } catch (IOException e) {
             // Silent close.
+        } finally {
+            /**
+             * For creating FileInputStream by using FileDescriptor, the file descriptor will not
+             * be closed after FileInputStream closed.
+             */
+            IOUtils.closeQuietly(mParcelFileDescriptor);
+        }
+
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+            mHandlerThread = null;
         }
     }
-};
+}
diff --git a/src/com/android/documentsui/archives/WriteableArchive.java b/src/com/android/documentsui/archives/WriteableArchive.java
index 27e4369..756a644 100644
--- a/src/com/android/documentsui/archives/WriteableArchive.java
+++ b/src/com/android/documentsui/archives/WriteableArchive.java
@@ -19,33 +19,30 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.CancellationSignal;
+import android.os.FileUtils;
 import android.os.OperationCanceledException;
-import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
 import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
 import android.util.Log;
 
-import com.android.internal.annotations.GuardedBy;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
-import libcore.io.IoUtils;
-
-import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
+
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.TimeUnit;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
 
 /**
  * Provides basic implementation for creating archives.
@@ -59,7 +56,7 @@
     private final Set<String> mPendingEntries = new HashSet<>();
     private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
     @GuardedBy("mEntries")
-    private final ZipOutputStream mZipOutputStream;
+    private final ZipArchiveOutputStream mZipOutputStream;
     private final AutoCloseOutputStream mOutputStream;
 
     /**
@@ -77,17 +74,17 @@
             throw new IllegalStateException("Unsupported access mode.");
         }
 
-        addEntry(null /* no parent */, new ZipEntry("/"));  // Root entry.
+        addEntry(null /* no parent */, new ZipArchiveEntry("/"));  // Root entry.
         mOutputStream = new AutoCloseOutputStream(fd);
-        mZipOutputStream = new ZipOutputStream(mOutputStream);
+        mZipOutputStream = new ZipArchiveOutputStream(mOutputStream);
     }
 
-    private void addEntry(@Nullable ZipEntry parentEntry, ZipEntry entry) {
+    private void addEntry(@Nullable ZipArchiveEntry parentEntry, ZipArchiveEntry entry) {
         final String entryPath = getEntryPath(entry);
         synchronized (mEntries) {
             if (entry.isDirectory()) {
                 if (!mTree.containsKey(entryPath)) {
-                    mTree.put(entryPath, new ArrayList<ZipEntry>());
+                    mTree.put(entryPath, new ArrayList<>());
                 }
             }
             mEntries.put(entryPath, entry);
@@ -115,7 +112,7 @@
      * @param descriptor File descriptor for the archive's contents.
      * @param archiveUri Uri of the archive document.
      * @param accessMode Access mode for the archive {@see ParcelFileDescriptor}.
-     * @param Uri notificationUri Uri for notifying that the archive file has changed.
+     * @param notificationUri notificationUri Uri for notifying that the archive file has changed.
      */
     @VisibleForTesting
     public static WriteableArchive createForParcelFileDescriptor(
@@ -128,7 +125,7 @@
         } catch (Exception e) {
             // Since the method takes ownership of the passed descriptor, close it
             // on exception.
-            IoUtils.closeQuietly(descriptor);
+            FileUtils.closeQuietly(descriptor);
             throw e;
         }
     }
@@ -142,17 +139,19 @@
                 "Mismatching archive Uri. Expected: %s, actual: %s.");
 
         final boolean isDirectory = Document.MIME_TYPE_DIR.equals(mimeType);
-        ZipEntry entry;
+        ZipArchiveEntry entry;
         String entryPath;
 
         synchronized (mEntries) {
-            final ZipEntry parentEntry = mEntries.get(parsedParentId.mPath);
+            final ZipArchiveEntry parentEntry =
+                    (ZipArchiveEntry) mEntries.get(parsedParentId.mPath);
 
             if (parentEntry == null) {
                 throw new FileNotFoundException();
             }
 
-            if (displayName.indexOf("/") != -1 || ".".equals(displayName) || "..".equals(displayName)) {
+            if (displayName.indexOf("/") != -1 || ".".equals(displayName)
+                    || "..".equals(displayName)) {
                 throw new IllegalStateException("Display name contains invalid characters.");
             }
 
@@ -162,9 +161,10 @@
 
 
             assert(parentEntry.getName().endsWith("/"));
-            final String parentName = "/".equals(parentEntry.getName()) ? "" : parentEntry.getName();
+            final String parentName = "/".equals(parentEntry.getName())
+                    ? "" : parentEntry.getName();
             final String entryName = parentName + displayName + (isDirectory ? "/" : "");
-            entry = new ZipEntry(entryName);
+            entry = new ZipArchiveEntry(entryName);
             entryPath = getEntryPath(entry);
             entry.setSize(0);
 
@@ -185,7 +185,8 @@
         } else {
             try {
                 synchronized (mEntries) {
-                    mZipOutputStream.putNextEntry(entry);
+                    mZipOutputStream.putArchiveEntry(entry);
+                    mZipOutputStream.closeArchiveEntry();
                 }
             } catch (IOException e) {
                 throw new IllegalStateException(
@@ -206,9 +207,9 @@
         MorePreconditions.checkArgumentEquals(mArchiveUri, parsedId.mArchiveUri,
                 "Mismatching archive Uri. Expected: %s, actual: %s.");
 
-        final ZipEntry entry;
+        final ZipArchiveEntry entry;
         synchronized (mEntries) {
-            entry = mEntries.get(parsedId.mPath);
+            entry = (ZipArchiveEntry) mEntries.get(parsedId.mPath);
             if (entry == null) {
                 throw new FileNotFoundException();
             }
@@ -238,7 +239,7 @@
                                     new ParcelFileDescriptor.AutoCloseInputStream(inputPipe)) {
                                 try {
                                     synchronized (mEntries) {
-                                        mZipOutputStream.putNextEntry(entry);
+                                        mZipOutputStream.putArchiveEntry(entry);
                                         final byte buffer[] = new byte[32 * 1024];
                                         int bytes;
                                         long size = 0;
@@ -250,7 +251,7 @@
                                             size += bytes;
                                         }
                                         entry.setSize(size);
-                                        mZipOutputStream.closeEntry();
+                                        mZipOutputStream.closeArchiveEntry();
                                     }
                                 } catch (IOException e) {
                                     // Catch the exception before the outer try-with-resource closes
@@ -270,8 +271,8 @@
                         }
                     });
         } catch (RejectedExecutionException e) {
-            IoUtils.closeQuietly(pipe[0]);
-            IoUtils.closeQuietly(pipe[1]);
+            FileUtils.closeQuietly(pipe[0]);
+            FileUtils.closeQuietly(pipe[1]);
             throw new IllegalStateException("Failed to initialize pipe.");
         }
 
@@ -297,8 +298,8 @@
         synchronized (mEntries) {
             for (final String path : mPendingEntries) {
                 try {
-                    mZipOutputStream.putNextEntry(mEntries.get(path));
-                    mZipOutputStream.closeEntry();
+                    mZipOutputStream.putArchiveEntry(mEntries.get(path));
+                    mZipOutputStream.closeArchiveEntry();
                 } catch (IOException e) {
                     Log.e(TAG, "Failed to flush empty entries.", e);
                 }
@@ -311,6 +312,6 @@
             }
         }
 
-        IoUtils.closeQuietly(mOutputStream);
+        FileUtils.closeQuietly(mOutputStream);
     }
-};
+}
diff --git a/src/com/android/documentsui/base/ConfirmationCallback.java b/src/com/android/documentsui/base/ConfirmationCallback.java
index a6ddb5d..c46ee6e 100644
--- a/src/com/android/documentsui/base/ConfirmationCallback.java
+++ b/src/com/android/documentsui/base/ConfirmationCallback.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.base;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/src/com/android/documentsui/base/DebugFlags.java b/src/com/android/documentsui/base/DebugFlags.java
index 4c4b9bc..7e0a70e 100644
--- a/src/com/android/documentsui/base/DebugFlags.java
+++ b/src/com/android/documentsui/base/DebugFlags.java
@@ -29,17 +29,17 @@
 
     private DebugFlags() {}
 
-    private static String mQvPackage;
+    private static String sQvPackage;
     private static boolean sDocumentDetailsEnabled;
     private static int sForcedPageOffset = -1;
     private static int sForcedPageLimit = -1;
 
     public static void setQuickViewer(@Nullable String qvPackage) {
-        mQvPackage = qvPackage;
+        sQvPackage = qvPackage;
     }
 
     public static @Nullable String getQuickViewer() {
-        return mQvPackage;
+        return sQvPackage;
     }
 
     public static void setDocumentDetailsEnabled(boolean enabled) {
diff --git a/src/com/android/documentsui/base/DocumentInfo.java b/src/com/android/documentsui/base/DocumentInfo.java
index a13ad98..89f6039 100644
--- a/src/com/android/documentsui/base/DocumentInfo.java
+++ b/src/com/android/documentsui/base/DocumentInfo.java
@@ -16,23 +16,26 @@
 
 package com.android.documentsui.base;
 
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
+
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.FileUtils;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsProvider;
-import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
 
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.roots.RootCursorWrapper;
 
-import libcore.io.IoUtils;
-
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.FileNotFoundException;
@@ -48,6 +51,7 @@
  * Representation of a {@link Document}.
  */
 public class DocumentInfo implements Durable, Parcelable {
+    private static final String TAG = "DocumentInfo";
     private static final int VERSION_INIT = 1;
     private static final int VERSION_SPLIT_URI = 2;
 
@@ -198,8 +202,8 @@
         } catch (Throwable t) {
             throw asFileNotFoundException(t);
         } finally {
-            IoUtils.closeQuietly(cursor);
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(client);
         }
     }
 
@@ -222,6 +226,7 @@
                 + ", isVirtual=" + isVirtual()
                 + ", isDeleteSupported=" + isDeleteSupported()
                 + ", isCreateSupported=" + isCreateSupported()
+                + ", isMoveSupported=" + isMoveSupported()
                 + ", isRenameSupported=" + isRenameSupported()
                 + ", isMetadataSupported=" + isMetadataSupported()
                 + "} @ "
@@ -323,6 +328,9 @@
     }
 
     public static String getCursorString(Cursor cursor, String columnName) {
+        if (cursor == null) {
+            return null;
+        }
         final int index = cursor.getColumnIndex(columnName);
         return (index != -1) ? cursor.getString(index) : null;
     }
@@ -331,6 +339,10 @@
      * Missing or null values are returned as -1.
      */
     public static long getCursorLong(Cursor cursor, String columnName) {
+        if (cursor == null) {
+            return -1;
+        }
+
         final int index = cursor.getColumnIndex(columnName);
         if (index == -1) return -1;
         final String value = cursor.getString(index);
@@ -346,6 +358,10 @@
      * Missing or null values are returned as 0.
      */
     public static int getCursorInt(Cursor cursor, String columnName) {
+        if (cursor == null) {
+            return 0;
+        }
+
         final int index = cursor.getColumnIndex(columnName);
         return (index != -1) ? cursor.getInt(index) : 0;
     }
@@ -369,7 +385,14 @@
     public static void addMimeTypes(ContentResolver resolver, Uri uri, Set<String> mimeTypes) {
         assert(uri != null);
         if ("content".equals(uri.getScheme())) {
-            mimeTypes.add(resolver.getType(uri));
+            final String type = resolver.getType(uri);
+            if (type != null) {
+                mimeTypes.add(type);
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "resolver.getType(uri) return null, url:" + uri.toSafeString());
+                }
+            }
             final String[] streamTypes = resolver.getStreamTypes(uri, "*/*");
             if (streamTypes != null) {
                 mimeTypes.addAll(Arrays.asList(streamTypes));
@@ -383,8 +406,7 @@
         }
 
         if (doc.derivedUri == null) {
-            doc.deriveFields();
-            assert(doc.derivedUri != null);
+            return "<DocumentInfo null derivedUri>";
         }
         return doc.derivedUri.toString();
     }
diff --git a/src/com/android/documentsui/base/DocumentStack.java b/src/com/android/documentsui/base/DocumentStack.java
index f30c43a..06e00f1 100644
--- a/src/com/android/documentsui/base/DocumentStack.java
+++ b/src/com/android/documentsui/base/DocumentStack.java
@@ -16,8 +16,9 @@
 
 package com.android.documentsui.base;
 
+import static androidx.core.util.Preconditions.checkArgument;
+
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.content.ContentResolver;
 import android.database.Cursor;
@@ -125,13 +126,17 @@
 
     public void push(DocumentInfo info) {
         checkArgument(!mList.contains(info));
-        if (DEBUG) Log.d(TAG, "Adding doc to stack: " + info);
+        if (DEBUG) {
+            Log.d(TAG, "Adding doc to stack: " + info);
+        }
         mList.addLast(info);
         mStackTouched = true;
     }
 
     public DocumentInfo pop() {
-        if (DEBUG) Log.d(TAG, "Popping doc off stack.");
+        if (DEBUG) {
+            Log.d(TAG, "Popping doc off stack.");
+        }
         final DocumentInfo result = mList.removeLast();
         mStackTouched = true;
 
@@ -139,7 +144,9 @@
     }
 
     public void popToRootDocument() {
-        if (DEBUG) Log.d(TAG, "Popping docs to root folder.");
+        if (DEBUG) {
+            Log.d(TAG, "Popping docs to root folder.");
+        }
         while (mList.size() > 1) {
             mList.removeLast();
         }
@@ -147,9 +154,18 @@
     }
 
     public void changeRoot(RootInfo root) {
-        if (DEBUG) Log.d(TAG, "Root changed to: " + root);
+        if (DEBUG) {
+            Log.d(TAG, "Root changed to: " + root);
+        }
         reset();
         mRoot = root;
+
+        // Add this for keep stack size is 1 on recent root.
+        if (root.isRecents()) {
+            DocumentInfo rootRecent = new DocumentInfo();
+            rootRecent.deriveFields();
+            push(rootRecent);
+        }
     }
 
     /** This will return true even when the initial location is set.
@@ -170,7 +186,7 @@
     }
 
     public boolean isRecents() {
-        return mRoot != null && mRoot.isRecents();
+        return mRoot != null && mRoot.isRecents() && size() == 1;
     }
 
     /**
@@ -178,7 +194,9 @@
      * {@link #mRoot} instead of making a copy.
      */
     public void reset(DocumentStack stack) {
-        if (DEBUG) Log.d(TAG, "Resetting the whole darn stack to: " + stack);
+        if (DEBUG) {
+            Log.d(TAG, "Resetting the whole darn stack to: " + stack);
+        }
 
         mList = stack.mList;
         mRoot = stack.mRoot;
diff --git a/src/com/android/documentsui/base/Events.java b/src/com/android/documentsui/base/Events.java
index c38f1a4..1e6be6c 100644
--- a/src/com/android/documentsui/base/Events.java
+++ b/src/com/android/documentsui/base/Events.java
@@ -16,7 +16,6 @@
 
 package com.android.documentsui.base;
 
-import android.graphics.Point;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
@@ -29,10 +28,6 @@
         return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
     }
 
-    public static boolean isActionMove(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_MOVE;
-    }
-
     public static boolean isActionDown(MotionEvent e) {
         return e.getActionMasked() == MotionEvent.ACTION_DOWN;
     }
@@ -49,22 +44,6 @@
         return e.getActionMasked() == MotionEvent.ACTION_POINTER_UP;
     }
 
-    public static boolean isActionCancel(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_CANCEL;
-    }
-
-    public static boolean isPrimaryButtonPressed(MotionEvent e) {
-        return e.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
-    }
-
-    public static boolean isSecondaryButtonPressed(MotionEvent e) {
-        return e.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
-    }
-
-    public static boolean isTertiaryButtonPressed(MotionEvent e) {
-        return e.isButtonPressed(MotionEvent.BUTTON_TERTIARY);
-    }
-
     public static boolean isCtrlKeyPressed(MotionEvent e) {
         return hasBit(e.getMetaState(), KeyEvent.META_CTRL_ON);
     }
@@ -77,20 +56,10 @@
         return hasBit(e.getMetaState(), KeyEvent.META_SHIFT_ON);
     }
 
-    public static boolean isTouchpadScroll(MotionEvent e) {
-        // Touchpad inputs are treated as mouse inputs, and when scrolling, there are no buttons
-        // returned.
-        return isMouseEvent(e) && isActionMove(e) && e.getButtonState() == 0;
-    }
-
     private static boolean hasBit(int metaState, int bit) {
         return (metaState & bit) != 0;
     }
 
-    public static Point getOrigin(MotionEvent e) {
-        return new Point((int) e.getX(), (int) e.getY());
-    }
-
     /**
      * @return true if keyCode is a known navigation code (e.g. up, down, home).
      */
@@ -109,15 +78,4 @@
                 return false;
         }
     }
-
-    /**
-     * Returns true if the event is a mouse drag event.
-     * @param e
-     * @return
-     */
-    public static boolean isMouseDragEvent(MotionEvent e) {
-        return isMouseEvent(e)
-                && isActionMove(e)
-                && isPrimaryButtonPressed(e);
-    }
 }
diff --git a/src/com/android/documentsui/base/Features.java b/src/com/android/documentsui/base/Features.java
index 7714353..b8bcf26 100644
--- a/src/com/android/documentsui/base/Features.java
+++ b/src/com/android/documentsui/base/Features.java
@@ -15,7 +15,6 @@
  */
 package com.android.documentsui.base;
 
-import android.annotation.BoolRes;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.UserManager;
@@ -23,15 +22,13 @@
 
 import com.android.documentsui.R;
 
+import androidx.annotation.BoolRes;
+
 /**
  * Provides access to feature flags configured in config.xml.
  */
 public interface Features {
 
-    // technically we want to check >= O, but we'd need to patch back the O version code :|
-    public static final boolean OMC_RUNTIME =
-            android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.N_MR1;
-
     boolean isArchiveCreationEnabled();
     boolean isCommandInterceptorEnabled();
     boolean isContentPagingEnabled();
@@ -47,6 +44,7 @@
     boolean isRemoteActionsEnabled();
     boolean isSystemKeyboardNavigationEnabled();
     boolean isVirtualFilesSharingEnabled();
+    boolean isDefaultRootInBrowseEnabled();
 
 
     /**
@@ -61,7 +59,8 @@
     void forceFeature(@BoolRes int feature, boolean enabled);
 
     public static Features create(Context context) {
-        return new RuntimeFeatures(context.getResources(), UserManager.get(context));
+        return new RuntimeFeatures(context.getResources(),
+                context.getSystemService(UserManager.class));
     }
 
     final class RuntimeFeatures implements Features {
@@ -168,5 +167,10 @@
         public boolean isVirtualFilesSharingEnabled() {
             return isEnabled(R.bool.feature_virtual_files_sharing);
         }
+
+        @Override
+        public boolean isDefaultRootInBrowseEnabled() {
+            return isEnabled(R.bool.feature_default_root_in_browse);
+        }
     }
 }
diff --git a/src/com/android/documentsui/base/MimeTypes.java b/src/com/android/documentsui/base/MimeTypes.java
index 44b61ca..e9d194b 100644
--- a/src/com/android/documentsui/base/MimeTypes.java
+++ b/src/com/android/documentsui/base/MimeTypes.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.base;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.provider.DocumentsContract.Document;
 
 import java.util.List;
@@ -25,16 +25,17 @@
     private MimeTypes() {}
 
     public static final String APK_TYPE = "application/vnd.android.package-archive";
+    public static final String GENERIC_TYPE = "application/*";
 
-    public static final String IMAGE_PREFIX = "image";
-    public static final String AUDIO_PREFIX = "audio";
-    public static final String VIDEO_PREFIX = "video";
+    public static final String IMAGE_MIME = "image/*";
+    public static final String AUDIO_MIME = "audio/*";
+    public static final String VIDEO_MIME = "video/*";
 
     /**
      * MIME types that are visual in nature. For example, they should always be
      * shown as thumbnails in list mode.
      */
-    public static final String[] VISUAL_MIMES = new String[] { "image/*", "video/*" };
+    public static final String[] VISUAL_MIMES = new String[] { IMAGE_MIME, VIDEO_MIME };
 
     public static @Nullable String[] splitMimeType(String mimeType) {
         final String[] groups = mimeType.split("/");
diff --git a/src/com/android/documentsui/base/RootInfo.java b/src/com/android/documentsui/base/RootInfo.java
index 340d614..dd82077 100644
--- a/src/com/android/documentsui/base/RootInfo.java
+++ b/src/com/android/documentsui/base/RootInfo.java
@@ -16,14 +16,16 @@
 
 package com.android.documentsui.base;
 
+import static android.provider.DocumentsContract.QUERY_ARG_MIME_TYPES;
+
 import static com.android.documentsui.base.DocumentInfo.getCursorInt;
 import static com.android.documentsui.base.DocumentInfo.getCursorLong;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 import static com.android.documentsui.base.Shared.compareToIgnoreCaseNullable;
 
-import android.annotation.IntDef;
-import android.annotation.Nullable;
+import androidx.annotation.IntDef;
+
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.drawable.Drawable;
@@ -35,13 +37,11 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.documentsui.DocumentsAccess;
 import com.android.documentsui.IconUtils;
 import com.android.documentsui.R;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -54,15 +54,17 @@
 public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
 
     private static final String TAG = "RootInfo";
+    private static final int LOAD_FROM_CONTENT_RESOLVER = -1;
     // private static final int VERSION_INIT = 1; // Not used anymore
     private static final int VERSION_DROP_TYPE = 2;
+    private static final int VERSION_SEARCH_TYPE = 3;
 
     // The values of these constants determine the sort order of various roots in the RootsFragment.
     @IntDef(flag = false, value = {
+            TYPE_RECENTS,
             TYPE_IMAGES,
             TYPE_VIDEO,
             TYPE_AUDIO,
-            TYPE_RECENTS,
             TYPE_DOWNLOADS,
             TYPE_LOCAL,
             TYPE_MTP,
@@ -72,10 +74,10 @@
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface RootType {}
-    public static final int TYPE_IMAGES = 1;
-    public static final int TYPE_VIDEO = 2;
-    public static final int TYPE_AUDIO = 3;
-    public static final int TYPE_RECENTS = 4;
+    public static final int TYPE_RECENTS = 1;
+    public static final int TYPE_IMAGES = 2;
+    public static final int TYPE_VIDEO = 3;
+    public static final int TYPE_AUDIO = 4;
     public static final int TYPE_DOWNLOADS = 5;
     public static final int TYPE_LOCAL = 6;
     public static final int TYPE_MTP = 7;
@@ -92,6 +94,7 @@
     public String documentId;
     public long availableBytes;
     public String mimeTypes;
+    public String queryArgs;
 
     /** Derived fields that aren't persisted */
     public String[] derivedMimeTypes;
@@ -117,6 +120,7 @@
         availableBytes = -1;
         mimeTypes = null;
         ejecting = false;
+        queryArgs = null;
 
         derivedMimeTypes = null;
         derivedIcon = 0;
@@ -127,6 +131,8 @@
     public void read(DataInputStream in) throws IOException {
         final int version = in.readInt();
         switch (version) {
+            case VERSION_SEARCH_TYPE:
+                queryArgs = DurableUtils.readNullableString(in);
             case VERSION_DROP_TYPE:
                 authority = DurableUtils.readNullableString(in);
                 rootId = DurableUtils.readNullableString(in);
@@ -146,7 +152,8 @@
 
     @Override
     public void write(DataOutputStream out) throws IOException {
-        out.writeInt(VERSION_DROP_TYPE);
+        out.writeInt(VERSION_SEARCH_TYPE);
+        DurableUtils.writeNullableString(out, queryArgs);
         DurableUtils.writeNullableString(out, authority);
         DurableUtils.writeNullableString(out, rootId);
         out.writeInt(flags);
@@ -193,6 +200,7 @@
         root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
         root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
         root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
+        root.queryArgs = getCursorString(cursor, Root.COLUMN_QUERY_ARGS);
         root.deriveFields();
         return root;
     }
@@ -200,9 +208,9 @@
     private void deriveFields() {
         derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
 
-        if (isHome()) {
+        if (isExternalStorageHome()) {
             derivedType = TYPE_LOCAL;
-            derivedIcon = R.drawable.ic_root_documents;
+            derivedIcon = LOAD_FROM_CONTENT_RESOLVER;
         } else if (isMtp()) {
             derivedType = TYPE_MTP;
             derivedIcon = R.drawable.ic_usb_storage;
@@ -220,13 +228,13 @@
             derivedIcon = R.drawable.ic_root_download;
         } else if (isImages()) {
             derivedType = TYPE_IMAGES;
-            derivedIcon = R.drawable.image_root_icon;
+            derivedIcon = LOAD_FROM_CONTENT_RESOLVER;
         } else if (isVideos()) {
             derivedType = TYPE_VIDEO;
-            derivedIcon = R.drawable.video_root_icon;
+            derivedIcon = LOAD_FROM_CONTENT_RESOLVER;
         } else if (isAudio()) {
             derivedType = TYPE_AUDIO;
-            derivedIcon = R.drawable.audio_root_icon;
+            derivedIcon = LOAD_FROM_CONTENT_RESOLVER;
         } else if (isRecents()) {
             derivedType = TYPE_RECENTS;
         } else {
@@ -244,7 +252,10 @@
         return authority == null && rootId == null;
     }
 
-    public boolean isHome() {
+    /*
+     * Return true, if the root is from ExternalStorage and the id is home. Otherwise, return false.
+     */
+    public boolean isExternalStorageHome() {
         // Note that "home" is the expected root id for the auto-created
         // user home directory on external storage. The "home" value should
         // match ExternalStorageProvider.ROOT_ID_HOME.
@@ -278,6 +289,9 @@
         return Providers.AUTHORITY_MTP.equals(authority);
     }
 
+    /*
+     * Return true, if the derivedType of this root is library type. Otherwise, return false.
+     */
     public boolean isLibrary() {
         return derivedType == TYPE_IMAGES
                 || derivedType == TYPE_VIDEO
@@ -285,6 +299,16 @@
                 || derivedType == TYPE_RECENTS;
     }
 
+    /*
+     * Return true, if the derivedType of this root is storage type. Otherwise, return false.
+     */
+    public boolean isStorage() {
+        return derivedType == TYPE_LOCAL
+                || derivedType == TYPE_MTP
+                || derivedType == TYPE_USB
+                || derivedType == TYPE_SD;
+    }
+
     public boolean hasSettings() {
         return (flags & Root.FLAG_HAS_SETTINGS) != 0;
     }
@@ -305,6 +329,10 @@
         return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
     }
 
+    public boolean supportsMimeTypesSearch() {
+        return queryArgs != null && queryArgs.contains(QUERY_ARG_MIME_TYPES);
+    }
+
     public boolean supportsEject() {
         return (flags & Root.FLAG_SUPPORTS_EJECT) != 0;
     }
@@ -329,8 +357,28 @@
         return (flags & Root.FLAG_REMOVABLE_USB) != 0;
     }
 
+    private Drawable loadMimeTypeIcon(Context context) {
+
+        if (isExternalStorageHome()) {
+            return IconUtils.loadMimeIcon(context, DocumentsContract.Document.MIME_TYPE_DIR);
+        }
+
+        switch (derivedType) {
+            case TYPE_IMAGES:
+                return IconUtils.loadMimeIcon(context, MimeTypes.IMAGE_MIME);
+            case TYPE_AUDIO:
+                return IconUtils.loadMimeIcon(context, MimeTypes.AUDIO_MIME);
+            case TYPE_VIDEO:
+                return IconUtils.loadMimeIcon(context, MimeTypes.VIDEO_MIME);
+            default:
+                return IconUtils.loadMimeIcon(context, MimeTypes.GENERIC_TYPE);
+        }
+    }
+
     public Drawable loadIcon(Context context) {
-        if (derivedIcon != 0) {
+        if (derivedIcon == LOAD_FROM_CONTENT_RESOLVER) {
+            return loadMimeTypeIcon(context);
+        } else if (derivedIcon != 0) {
             return context.getDrawable(derivedIcon);
         } else {
             return IconUtils.loadPackageIcon(context, authority, icon);
@@ -338,7 +386,10 @@
     }
 
     public Drawable loadDrawerIcon(Context context) {
-        if (derivedIcon != 0) {
+        if (derivedIcon == LOAD_FROM_CONTENT_RESOLVER) {
+            return IconUtils.applyTintColor(context, loadMimeTypeIcon(context),
+                    R.color.item_root_icon);
+        } else if (derivedIcon != 0) {
             return IconUtils.applyTintColor(context, derivedIcon, R.color.item_root_icon);
         } else {
             return IconUtils.loadPackageIcon(context, authority, icon);
@@ -346,7 +397,7 @@
     }
 
     public Drawable loadEjectIcon(Context context) {
-        return IconUtils.applyTintColor(context, R.drawable.ic_eject, R.color.item_eject_icon);
+        return IconUtils.applyTintColor(context, R.drawable.ic_eject, R.color.item_action_icon);
     }
 
     @Override
diff --git a/src/com/android/documentsui/base/Shared.java b/src/com/android/documentsui/base/Shared.java
index 638b5f4..ec13a50 100644
--- a/src/com/android/documentsui/base/Shared.java
+++ b/src/com/android/documentsui/base/Shared.java
@@ -18,9 +18,7 @@
 
 import static com.android.documentsui.base.SharedMinimal.TAG;
 
-import android.annotation.PluralsRes;
 import android.app.Activity;
-import android.app.AlertDialog;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -28,7 +26,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Looper;
 import android.provider.DocumentsContract;
 import android.provider.Settings;
@@ -48,6 +45,9 @@
 
 import javax.annotation.Nullable;
 
+import androidx.annotation.PluralsRes;
+import androidx.appcompat.app.AlertDialog;
+
 /** @hide */
 public final class Shared {
 
@@ -78,6 +78,11 @@
     public static final String EXTRA_QUERY = "query";
 
     /**
+     * Extra flag used to store chip's title of type String array in the bundle.
+     */
+    public static final String EXTRA_QUERY_CHIPS = "query_chips";
+
+    /**
      * Extra flag used to store state of type State in the bundle.
      */
     public static final String EXTRA_STATE = "state";
@@ -103,6 +108,11 @@
     public static final String EXTRA_IGNORE_STATE = "ignoreState";
 
     /**
+     * Extra flag used to store pick result state of PickResult type in the bundle.
+     */
+    public static final String EXTRA_PICK_RESULT = "pickResult";
+
+    /**
      * Extra for an Intent for enabling performance benchmark. Used only by tests.
      */
     public static final String EXTRA_BENCHMARK = "com.android.documentsui.benchmark";
@@ -184,6 +194,14 @@
         return sCollator.compare(lhs, rhs);
     }
 
+    private static boolean isSystemApp(ApplicationInfo ai) {
+        return (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
+    private static boolean isUpdatedSystemApp(ApplicationInfo ai) {
+        return (ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
+    }
+
     /**
      * Returns the calling package, possibly overridden by EXTRA_PACKAGE_NAME.
      * @param activity
@@ -195,9 +213,9 @@
         try {
             ApplicationInfo info =
                     activity.getPackageManager().getApplicationInfo(callingPackage, 0);
-            if (info.isSystemApp() || info.isUpdatedSystemApp()) {
+            if (isSystemApp(info) || isUpdatedSystemApp(info)) {
                 final String extra = activity.getIntent().getStringExtra(
-                        DocumentsContract.EXTRA_PACKAGE_NAME);
+                        Intent.EXTRA_PACKAGE_NAME);
                 if (extra != null && !TextUtils.isEmpty(extra)) {
                     callingPackage = extra;
                 }
@@ -243,6 +261,22 @@
         return context.getResources().getBoolean(R.bool.show_documents_root);
     }
 
+    /**
+     * Check config whether DocumentsUI is launcher enabled or not.
+     * @return true if "is_launcher_enabled" is true.
+     */
+    public static boolean isLauncherEnabled(Context context) {
+        return context.getResources().getBoolean(R.bool.is_launcher_enabled);
+    }
+
+    /**
+     * Check config has quick viewer package value or not.
+     * @return true if "trusted_quick_viewer_package" has value.
+     */
+    public static boolean hasQuickViewer(Context context) {
+        return !TextUtils.isEmpty(context.getString(R.string.trusted_quick_viewer_package));
+    }
+
     /*
      * Returns true if the local/device storage root must be visible (this also hides
      * the option to toggle visibility in the menu.)
diff --git a/src/com/android/documentsui/base/SharedMinimal.java b/src/com/android/documentsui/base/SharedMinimal.java
index 880ee49..86b6608 100644
--- a/src/com/android/documentsui/base/SharedMinimal.java
+++ b/src/com/android/documentsui/base/SharedMinimal.java
@@ -16,30 +16,9 @@
 
 package com.android.documentsui.base;
 
-import static android.os.Environment.isStandardDirectory;
-
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_ERROR;
-import static com.android.documentsui.ScopedAccessMetrics.SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY;
-import static com.android.documentsui.ScopedAccessMetrics.logInvalidScopedAccessRequest;
-
-import android.annotation.Nullable;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.net.Uri;
 import android.os.Build;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
-import android.provider.DocumentsContract;
-import android.text.TextUtils;
 import android.util.Log;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
 /**
  * Contains the minimum number of utilities (contants, helpers, etc...) that can be used by both the
  * main package and the minimal APK that's used by Android TV (and other devices).
@@ -51,197 +30,9 @@
 
     public static final String TAG = "Documents";
 
-    public static final boolean DEBUG = Build.IS_DEBUGGABLE;
+    public static final boolean DEBUG = !"user".equals(Build.TYPE);
     public static final boolean VERBOSE = DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
 
-    /**
-     * Special directory name representing the full volume of a scoped directory request.
-     */
-    public static final String DIRECTORY_ROOT = "ROOT_DIRECTORY";
-
-    /**
-     * Callback for {@link SharedMinimal#getUriPermission(Context, ContentProviderClient,
-     * StorageVolume, String, int, boolean, GetUriPermissionCallback)}.
-     */
-    public static interface GetUriPermissionCallback {
-
-        /**
-         * Evaluates the result of the request.
-         *
-         * @param file the path of the requested URI.
-         * @param volumeLabel user-friendly label of the volume.
-         * @param isRoot whether the requested directory is the root directory.
-         * @param isPrimary whether the requested volume is the primary storage volume.
-         * @param requestedUri the requested URI.
-         * @param rootUri the URI for the volume's root directory.
-         * @return whethe the result was sucessfully.
-         */
-        boolean onResult(File file, String volumeLabel, boolean isRoot, boolean isPrimary,
-                Uri requestedUri, Uri rootUri);
-    }
-
-    /**
-     * Gets the name of a directory name in the format that's used internally by the app
-     * (i.e., mapping {@code null} to {@link #DIRECTORY_ROOT});
-     * if necessary.
-     */
-    public static String getInternalDirectoryName(@Nullable String name) {
-        return name == null ? DIRECTORY_ROOT : name;
-    }
-
-    /**
-     * Gets the name of a directory name in the format that is used externally
-     * (i.e., mapping {@link #DIRECTORY_ROOT} to {@code null} if necessary);
-     */
-    @Nullable
-    public static String getExternalDirectoryName(String name) {
-        return name.equals(DIRECTORY_ROOT) ? null : name;
-    }
-
-    /**
-     * Gets the URI permission for the given volume and directory.
-     *
-     * @param context caller's context.
-     * @param storageClient storage provider client.
-     * @param storageVolume volume.
-     * @param directoryName directory name, or {@link #DIRECTORY_ROOT} for full volume.
-     * @param userId caller's user handle.
-     * @param logMetrics whether intermediate errors should be logged.
-     * @param callback callback that receives the results.
-     *
-     * @return whether the call was succesfull or not.
-     */
-    public static boolean getUriPermission(Context context,
-            ContentProviderClient storageClient, StorageVolume storageVolume,
-            String directoryName, int userId, boolean logMetrics,
-            GetUriPermissionCallback callback) {
-        if (DEBUG) {
-            Log.d(TAG, "getUriPermission() for volume " + storageVolume.dump() + ", directory "
-                    + directoryName + ", and user " + userId);
-        }
-        final boolean isRoot = directoryName.equals(DIRECTORY_ROOT);
-        final boolean isPrimary = storageVolume.isPrimary();
-
-        if (isRoot && isPrimary) {
-            if (DEBUG) Log.d(TAG, "root access requested on primary volume");
-            return false;
-        }
-
-        final File volumeRoot = storageVolume.getPathFile();
-        File file;
-        try {
-            file = isRoot ? volumeRoot : new File(volumeRoot, directoryName).getCanonicalFile();
-        } catch (IOException e) {
-            Log.e(TAG, "Could not get canonical file for volume " + storageVolume.dump()
-                    + " and directory " + directoryName);
-            if (logMetrics) logInvalidScopedAccessRequest(context, SCOPED_DIRECTORY_ACCESS_ERROR);
-            return false;
-        }
-        final StorageManager sm = context.getSystemService(StorageManager.class);
-
-        final String root, directory;
-        if (isRoot) {
-            root = volumeRoot.getAbsolutePath();
-            directory = ".";
-        } else {
-            root = file.getParent();
-            directory = file.getName();
-            // Verify directory is valid.
-            if (TextUtils.isEmpty(directory) || !isStandardDirectory(directory)) {
-                if (DEBUG) {
-                    Log.d(TAG, "Directory '" + directory + "' is not standard (full path: '"
-                            + file.getAbsolutePath() + "')");
-                }
-                if (logMetrics) {
-                    logInvalidScopedAccessRequest(context,
-                            SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY);
-                }
-                return false;
-            }
-        }
-
-        // Gets volume label and converted path.
-        String volumeLabel = null;
-        final List<VolumeInfo> volumes = sm.getVolumes();
-        if (DEBUG) Log.d(TAG, "Number of volumes: " + volumes.size());
-        File internalRoot = null;
-        for (VolumeInfo volume : volumes) {
-            if (isRightVolume(volume, root, userId)) {
-                internalRoot = volume.getInternalPathForUser(userId);
-                // Must convert path before calling getDocIdForFileCreateNewDir()
-                if (DEBUG) Log.d(TAG, "Converting " + root + " to " + internalRoot);
-                file = isRoot ? internalRoot : new File(internalRoot, directory);
-                volumeLabel = sm.getBestVolumeDescription(volume);
-                if (TextUtils.isEmpty(volumeLabel)) {
-                    volumeLabel = storageVolume.getDescription(context);
-                }
-                if (TextUtils.isEmpty(volumeLabel)) {
-                    volumeLabel = context.getString(android.R.string.unknownName);
-                    Log.w(TAG, "No volume description  for " + volume + "; using " + volumeLabel);
-                }
-                break;
-            }
-        }
-        if (internalRoot == null) {
-            // Should not happen on normal circumstances, unless app crafted an invalid volume
-            // using reflection or the list of mounted volumes changed.
-            Log.e(TAG, "Didn't find right volume for '" + storageVolume.dump() + "' on " + volumes);
-            return false;
-        }
-
-        final Uri requestedUri = getUriPermission(context, storageClient, file);
-        final Uri rootUri = internalRoot.equals(file) ? requestedUri
-                : getUriPermission(context, storageClient, internalRoot);
-
-        return callback.onResult(file, volumeLabel, isRoot, isPrimary, requestedUri, rootUri);
-    }
-
-    /**
-     * Creates an URI permission for the given file.
-     */
-    public static Uri getUriPermission(Context context, ContentProviderClient storageProvider,
-            File file) {
-        // Calls ExternalStorageProvider to get the doc id for the file
-        final Bundle bundle;
-        try {
-            bundle = storageProvider.call("getDocIdForFileCreateNewDir", file.getPath(), null);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Did not get doc id from External Storage provider for " + file, e);
-            logInvalidScopedAccessRequest(context, SCOPED_DIRECTORY_ACCESS_ERROR);
-            return null;
-        }
-        final String docId = bundle == null ? null : bundle.getString("DOC_ID");
-        if (docId == null) {
-            Log.e(TAG, "Did not get doc id from External Storage provider for " + file);
-            logInvalidScopedAccessRequest(context, SCOPED_DIRECTORY_ACCESS_ERROR);
-            return null;
-        }
-        if (DEBUG) Log.d(TAG, "doc id for " + file + ": " + docId);
-
-        final Uri uri = DocumentsContract.buildTreeDocumentUri(Providers.AUTHORITY_STORAGE, docId);
-        if (uri == null) {
-            Log.e(TAG, "Could not get URI for doc id " + docId);
-            return null;
-        }
-        if (DEBUG) Log.d(TAG, "URI for " + file + ": " + uri);
-        return uri;
-    }
-
-    private static boolean isRightVolume(VolumeInfo volume, String root, int userId) {
-        final File userPath = volume.getPathForUser(userId);
-        final String path = userPath == null ? null : volume.getPathForUser(userId).getPath();
-        final boolean isMounted = volume.isMountedReadable();
-        if (DEBUG)
-            Log.d(TAG, "Volume: " + volume
-                    + "\n\tuserId: " + userId
-                    + "\n\tuserPath: " + userPath
-                    + "\n\troot: " + root
-                    + "\n\tpath: " + path
-                    + "\n\tisMounted: " + isMounted);
-
-        return isMounted && root.equals(path);
-    }
-
     private SharedMinimal() {
         throw new UnsupportedOperationException("provides static fields only");
     }
diff --git a/src/com/android/documentsui/base/State.java b/src/com/android/documentsui/base/State.java
index 13a28ef..1584631 100644
--- a/src/com/android/documentsui/base/State.java
+++ b/src/com/android/documentsui/base/State.java
@@ -16,12 +16,13 @@
 
 package com.android.documentsui.base;
 
-import android.annotation.IntDef;
 import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseArray;
 
+import androidx.annotation.IntDef;
+
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.sorting.SortModel;
@@ -115,6 +116,33 @@
         }
     }
 
+    /**
+     * Check current action should have preview function or not.
+     * @return True, if the action should have preview.
+     */
+    public boolean shouldShowPreview() {
+        return action == ACTION_GET_CONTENT
+                || action == ACTION_OPEN_TREE
+                || action == ACTION_OPEN;
+    }
+
+    /**
+     * Check the action is file picking and acceptMimes are all images type or not.
+     * @return True, if acceptMimes are all image type and action is file picking.
+     */
+    public boolean isPhotoPicking() {
+        if (action != ACTION_GET_CONTENT && action != ACTION_OPEN || acceptMimes == null) {
+            return false;
+        }
+
+        for (String mimeType : acceptMimes) {
+            if (!MimeTypes.mimeMatches(MimeTypes.IMAGE_MIME, mimeType)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -162,7 +190,7 @@
         public State createFromParcel(Parcel in, ClassLoader loader) {
             final State state = new State();
             state.action = in.readInt();
-            state.acceptMimes = in.readStringArray();
+            state.acceptMimes = in.createStringArray();
             state.allowMultiple = in.readInt() != 0;
             state.localOnly = in.readInt() != 0;
             state.showDeviceStorageOption = in.readInt() != 0;
diff --git a/src/com/android/documentsui/clipping/ClipStorage.java b/src/com/android/documentsui/clipping/ClipStorage.java
index 9da3d9a..8db9b3c 100644
--- a/src/com/android/documentsui/clipping/ClipStorage.java
+++ b/src/com/android/documentsui/clipping/ClipStorage.java
@@ -19,7 +19,7 @@
 import android.content.SharedPreferences;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Log;
@@ -164,7 +164,9 @@
         try {
             Os.symlink(primary.getAbsolutePath(), link.getAbsolutePath());
         } catch (ErrnoException e) {
-            e.rethrowAsIOException();
+            IOException newException = new IOException(e.getMessage());
+            newException.initCause(e);
+            throw newException;
         }
         return link;
     }
diff --git a/src/com/android/documentsui/clipping/DocumentClipper.java b/src/com/android/documentsui/clipping/DocumentClipper.java
index bc61137..fe85e27 100644
--- a/src/com/android/documentsui/clipping/DocumentClipper.java
+++ b/src/com/android/documentsui/clipping/DocumentClipper.java
@@ -20,12 +20,11 @@
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.net.Uri;
-import android.support.annotation.Nullable;
+
+import androidx.recyclerview.selection.Selection;
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
-import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.selection.Selection;
 import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.services.FileOperations;
 
@@ -47,7 +46,7 @@
      * Returns {@link ClipData} representing the selection, or null if selection is empty,
      * or cannot be converted.
      */
-    ClipData getClipDataForDocuments(Function<String, Uri> uriBuilder, Selection selection,
+    ClipData getClipDataForDocuments(Function<String, Uri> uriBuilder, Selection<String> selection,
             @OpType int opType);
 
     /**
@@ -63,13 +62,13 @@
     /**
      * Puts {@code ClipData} in a primary clipboard, describing a copy operation
      */
-    void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection selection);
+    void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection<String> selection);
 
     /**
      *  Puts {@Code ClipData} in a primary clipboard, describing a cut operation
      */
     void clipDocumentsForCut(
-            Function<String, Uri> uriBuilder, Selection selection, DocumentInfo parent);
+            Function<String, Uri> uriBuilder, Selection<String> selection, DocumentInfo parent);
 
     /**
      * Copies documents from clipboard. It's the same as {@link #copyFromClipData} with clipData
diff --git a/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java b/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java
index bb9f062..d6c0bd5 100644
--- a/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java
+++ b/src/com/android/documentsui/clipping/RuntimeDocumentClipper.java
@@ -24,15 +24,15 @@
 import android.net.Uri;
 import android.os.PersistableBundle;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.Selection;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.Features;
-import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
-import com.android.documentsui.selection.Selection;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
@@ -90,7 +90,7 @@
 
     @Override
     public ClipData getClipDataForDocuments(
-        Function<String, Uri> uriBuilder, Selection selection, @OpType int opType) {
+        Function<String, Uri> uriBuilder, Selection<String> selection, @OpType int opType) {
 
         assert(selection != null);
 
@@ -190,7 +190,8 @@
     }
 
     @Override
-    public void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection selection) {
+    public void clipDocumentsForCopy(
+            Function<String, Uri> uriBuilder, Selection<String> selection) {
         ClipData data =
                 getClipDataForDocuments(uriBuilder, selection, FileOperationService.OPERATION_COPY);
         assert(data != null);
@@ -200,7 +201,7 @@
 
     @Override
     public void clipDocumentsForCut(
-            Function<String, Uri> uriBuilder, Selection selection, DocumentInfo parent) {
+            Function<String, Uri> uriBuilder, Selection<String> selection, DocumentInfo parent) {
         assert(!selection.isEmpty());
         assert(parent.derivedUri != null);
 
@@ -322,12 +323,6 @@
 
     private static ClipData createClipData(
             ClipDescription description, ArrayList<ClipData.Item> clipItems) {
-
-        // technically we want to check >= O, but we'd need to patch back the O version code :|
-        if (Features.OMC_RUNTIME) {
-            return new ClipData(description, clipItems);
-        }
-
         ClipData clip = new ClipData(description, clipItems.get(0));
         for (int i = 1; i < clipItems.size(); i++) {
             clip.addItem(clipItems.get(i));
diff --git a/src/com/android/documentsui/clipping/UrisSupplier.java b/src/com/android/documentsui/clipping/UrisSupplier.java
index 37aeb54..6679347 100644
--- a/src/com/android/documentsui/clipping/UrisSupplier.java
+++ b/src/com/android/documentsui/clipping/UrisSupplier.java
@@ -25,12 +25,13 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
-import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.selection.Selection;
+
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.base.Shared;
-import com.android.documentsui.selection.Selection;
 import com.android.documentsui.services.FileOperation;
 
 import java.io.File;
@@ -82,7 +83,7 @@
     }
 
     public static UrisSupplier create(
-            Selection selection, Function<String, Uri> uriBuilder, ClipStore storage)
+            Selection<String> selection, Function<String, Uri> uriBuilder, ClipStore storage)
             throws IOException {
 
         List<Uri> uris = new ArrayList<>(selection.size());
diff --git a/src/com/android/documentsui/dirlist/AccessibilityEventRouter.java b/src/com/android/documentsui/dirlist/AccessibilityEventRouter.java
index 9a8b342..e12bca1 100644
--- a/src/com/android/documentsui/dirlist/AccessibilityEventRouter.java
+++ b/src/com/android/documentsui/dirlist/AccessibilityEventRouter.java
@@ -17,13 +17,16 @@
 package com.android.documentsui.dirlist;
 
 import android.os.Bundle;
-import android.support.v4.view.AccessibilityDelegateCompat;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerViewAccessibilityDelegate;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.view.AccessibilityDelegateCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+
 import java.util.function.Function;
 
 /**
@@ -44,17 +47,29 @@
 
     private final ItemDelegate mItemDelegate;
     private final Function<View, Boolean> mClickCallback;
+    private final Function<View, Boolean> mLongClickCallback;
 
     public AccessibilityEventRouter(
-            RecyclerView recyclerView, Function<View, Boolean> clickCallback) {
+            RecyclerView recyclerView, @NonNull Function<View, Boolean> clickCallback,
+            @Nullable Function<View, Boolean> longClickCallback) {
         super(recyclerView);
         mClickCallback = clickCallback;
+        mLongClickCallback = longClickCallback;
         mItemDelegate = new ItemDelegate(this) {
             @Override
             public void onInitializeAccessibilityNodeInfo(View host,
                     AccessibilityNodeInfoCompat info) {
                 super.onInitializeAccessibilityNodeInfo(host, info);
-                info.addAction(AccessibilityActionCompat.ACTION_CLICK);
+                final RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(host);
+                // if the viewHolder is a DocumentsHolder instance and the ItemDetails
+                // is null, it can't be clicked
+                if (holder instanceof DocumentHolder) {
+                    if (((DocumentHolder)holder).getItemDetails() != null) {
+                        addAction(info);
+                    }
+                } else {
+                    addAction(info);
+                }
                 info.setSelected(host.isActivated());
             }
 
@@ -63,6 +78,9 @@
                 // We are only handling click events; route all other to default implementation
                 if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
                     return mClickCallback.apply(host);
+                } else if (action == AccessibilityNodeInfoCompat.ACTION_LONG_CLICK
+                        && mLongClickCallback != null) {
+                    return mLongClickCallback.apply(host);
                 }
                 return super.performAccessibilityAction(host, action, args);
             }
@@ -73,4 +91,11 @@
     public AccessibilityDelegateCompat getItemDelegate() {
         return mItemDelegate;
     }
+
+    private void addAction(AccessibilityNodeInfoCompat info) {
+        info.addAction(AccessibilityActionCompat.ACTION_CLICK);
+        if (mLongClickCallback != null) {
+            info.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/documentsui/dirlist/AnimationView.java b/src/com/android/documentsui/dirlist/AnimationView.java
index 7f75d3b..d17bddf 100644
--- a/src/com/android/documentsui/dirlist/AnimationView.java
+++ b/src/com/android/documentsui/dirlist/AnimationView.java
@@ -16,8 +16,9 @@
 
 package com.android.documentsui.dirlist;
 
-import android.annotation.IntDef;
-import android.app.FragmentTransaction;
+import androidx.annotation.IntDef;
+import androidx.fragment.app.FragmentTransaction;
+
 import android.content.Context;
 import android.os.Bundle;
 import android.util.AttributeSet;
diff --git a/src/com/android/documentsui/dirlist/AppsRowItemData.java b/src/com/android/documentsui/dirlist/AppsRowItemData.java
new file mode 100644
index 0000000..7c6d9c7
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/AppsRowItemData.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 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.documentsui.dirlist;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.sidebar.AppItem;
+import com.android.documentsui.sidebar.Item;
+import com.android.documentsui.sidebar.RootItem;
+
+/**
+ * A bacis data class stored data which apps row chip required.
+ * This is abstract class and it will be implemented by {@link AppData} and {@link RootData},
+ * both classes are different by the item is {@link AppItem} or {@link RootItem}.
+ */
+public abstract class AppsRowItemData {
+
+    private final String mTitle;
+    protected final ActionHandler mActionHandler;
+
+    public AppsRowItemData(Item item, ActionHandler actionHandler) {
+        mTitle = item.title;
+        mActionHandler = actionHandler;
+    }
+
+    public final String getTitle() {
+        return mTitle;
+    }
+
+    protected abstract Drawable getIconDrawable(Context context);
+    protected abstract void onClicked();
+    protected abstract boolean showExitIcon();
+
+    public static class AppData extends AppsRowItemData {
+
+        private final ResolveInfo mResolveInfo;
+
+        public AppData(AppItem item, ActionHandler actionHandler) {
+            super(item, actionHandler);
+            mResolveInfo = item.info;
+        }
+
+        @Override
+        protected Drawable getIconDrawable(Context context) {
+            return mResolveInfo.loadIcon(context.getPackageManager());
+        }
+
+        @Override
+        protected void onClicked() {
+            mActionHandler.openRoot(mResolveInfo);
+        }
+
+        @Override
+        protected boolean showExitIcon() {
+            return true;
+        }
+    }
+
+    public static class RootData extends AppsRowItemData {
+
+        private final RootInfo mRootInfo;
+
+        public RootData(RootItem item, ActionHandler actionHandler) {
+            super(item, actionHandler);
+            mRootInfo = item.root;
+        }
+
+        @Override
+        protected Drawable getIconDrawable(Context context) {
+            return mRootInfo.loadIcon(context);
+        }
+
+        @Override
+        protected void onClicked() {
+            mActionHandler.openRoot(mRootInfo);
+        }
+
+        @Override
+        protected boolean showExitIcon() {
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/AppsRowManager.java b/src/com/android/documentsui/dirlist/AppsRowManager.java
new file mode 100644
index 0000000..cace69f
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/AppsRowManager.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2018 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.documentsui.dirlist;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.R;
+import com.android.documentsui.base.State;
+import com.android.documentsui.dirlist.AppsRowItemData.AppData;
+import com.android.documentsui.dirlist.AppsRowItemData.RootData;
+import com.android.documentsui.sidebar.AppItem;
+import com.android.documentsui.sidebar.Item;
+import com.android.documentsui.sidebar.RootItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A manager class stored apps row chip data list. Data will be synced by RootsFragment.
+ */
+public class AppsRowManager {
+
+    private final ActionHandler mActionHandler;
+    private final List<AppsRowItemData> mDataList;
+
+    public AppsRowManager(ActionHandler handler) {
+        mDataList = new ArrayList<>();
+        mActionHandler = handler;
+    }
+
+    public List<AppsRowItemData> updateList(List<Item> itemList) {
+        mDataList.clear();
+        for (Item item : itemList) {
+            if (item instanceof RootItem) {
+                mDataList.add(new RootData((RootItem) item, mActionHandler));
+            } else {
+                mDataList.add(new AppData((AppItem) item, mActionHandler));
+            }
+        }
+        return mDataList;
+    }
+
+    private boolean shouldShow(State state) {
+        boolean isHiddenAction = state.action == State.ACTION_CREATE
+                || state.action == State.ACTION_OPEN_TREE
+                || state.action == State.ACTION_PICK_COPY_DESTINATION;
+        return state.stack.isRecents() && !isHiddenAction && mDataList.size() > 0;
+    }
+
+    public void updateView(BaseActivity activity) {
+        final View appsRowLayout = activity.findViewById(R.id.apps_row);
+
+        if (!shouldShow(activity.getDisplayState())) {
+            appsRowLayout.setVisibility(View.GONE);
+            return;
+        }
+
+        appsRowLayout.setVisibility(View.VISIBLE);
+        final LinearLayout appsGroup = activity.findViewById(R.id.apps_group);
+        appsGroup.removeAllViews();
+
+        final LayoutInflater inflater = activity.getLayoutInflater();
+        for (AppsRowItemData data : mDataList) {
+            View item = inflater.inflate(R.layout.apps_item, appsGroup, false);
+            bindView(item, data);
+            appsGroup.addView(item);
+        }
+    }
+
+    private void bindView(View view, AppsRowItemData data) {
+        final ImageView app_icon = view.findViewById(R.id.app_icon);
+        final TextView title = view.findViewById(android.R.id.title);
+        final ImageView exit_icon = view.findViewById(R.id.exit_icon);
+
+        app_icon.setImageDrawable(data.getIconDrawable(view.getContext()));
+        title.setText(data.getTitle());
+        exit_icon.setVisibility(data.showExitIcon() ? View.VISIBLE : View.GONE);
+        view.setOnClickListener(v -> data.onClicked());
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java b/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java
index 2af3850..d684c88 100644
--- a/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java
+++ b/src/com/android/documentsui/dirlist/DirectoryAddonsAdapter.java
@@ -16,13 +16,15 @@
 
 package com.android.documentsui.dirlist;
 
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView.AdapterDataObserver;
 import android.view.ViewGroup;
 
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
+
 import com.android.documentsui.Model;
 import com.android.documentsui.Model.Update;
 import com.android.documentsui.base.EventListener;
+import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.Message.HeaderMessage;
 import com.android.documentsui.dirlist.Message.InflateMessage;
 
@@ -71,12 +73,19 @@
         return new GridLayoutManager.SpanSizeLookup() {
             @Override
             public int getSpanSize(int position) {
+                final int columnCount = mEnv.getColumnCount();
                 // Make layout whitespace span the grid. This has the effect of breaking
                 // grid rows whenever layout whitespace is encountered.
                 if (getItemViewType(position) == ITEM_TYPE_SECTION_BREAK
                         || getItemViewType(position) == ITEM_TYPE_HEADER_MESSAGE
                         || getItemViewType(position) == ITEM_TYPE_INFLATED_MESSAGE) {
-                    return mEnv.getColumnCount();
+                    return columnCount;
+                } else if (mEnv.getDisplayState().isPhotoPicking()
+                        && mEnv.getDisplayState().derivedMode == State.MODE_GRID) {
+                    // If on photo picking state and grid mode,
+                    // the UI should show 3 images a row or 2 folders a row.
+                    return getItemViewType(position) == ITEM_TYPE_DIRECTORY
+                            ? Math.min(columnCount, 3) : Math.min(columnCount, 2);
                 } else {
                     return 1;
                 }
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index e48cf9d..08a64da 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -22,52 +22,61 @@
 import static com.android.documentsui.base.State.MODE_GRID;
 import static com.android.documentsui.base.State.MODE_LIST;
 
-import android.annotation.DimenRes;
-import android.annotation.FractionRes;
-import android.annotation.IntDef;
-import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.RecyclerListener;
-import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.ContextMenu;
-import android.view.GestureDetector;
 import android.view.LayoutInflater;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 
+import androidx.annotation.DimenRes;
+import androidx.annotation.FractionRes;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.Selection;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.SelectionTracker.SelectionPredicate;
+import androidx.recyclerview.selection.StorageStrategy;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.RecyclerListener;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
 import com.android.documentsui.ActionHandler;
 import com.android.documentsui.ActionModeController;
 import com.android.documentsui.BaseActivity;
-import com.android.documentsui.BaseActivity.RetainedState;
+import com.android.documentsui.ContentLock;
+import com.android.documentsui.DocsSelectionHelper.DocDetailsLookup;
 import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.DragHoverListener;
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
 import com.android.documentsui.Injector.ContentScoped;
 import com.android.documentsui.Injector.Injected;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.Model;
 import com.android.documentsui.R;
@@ -86,20 +95,6 @@
 import com.android.documentsui.clipping.UrisSupplier;
 import com.android.documentsui.dirlist.AnimationView.AnimationType;
 import com.android.documentsui.picker.PickActivity;
-import com.android.documentsui.selection.BandSelectionHelper;
-import com.android.documentsui.selection.ContentLock;
-import com.android.documentsui.selection.DefaultBandHost;
-import com.android.documentsui.selection.DefaultBandPredicate;
-import com.android.documentsui.selection.GestureRouter;
-import com.android.documentsui.selection.GestureSelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.MotionInputHandler;
-import com.android.documentsui.selection.MouseInputHandler;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-import com.android.documentsui.selection.TouchEventRouter;
-import com.android.documentsui.selection.TouchInputHandler;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
@@ -110,6 +105,7 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -128,7 +124,6 @@
     public static final int REQUEST_COPY_DESTINATION = 1;
 
     static final String TAG = "DirectoryFragment";
-    private static final int LOADER_ID = 42;
 
     private static final int CACHE_EVICT_LIMIT = 100;
     private static final int REFRESH_SPINNER_TIMEOUT = 500;
@@ -146,7 +141,7 @@
 
     @Injected
     @ContentScoped
-    private SelectionHelper mSelectionMgr;
+    private SelectionTracker<String> mSelectionMgr;
 
     @Injected
     @ContentScoped
@@ -160,10 +155,9 @@
     @ContentScoped
     private ActionModeController mActionModeController;
 
-    private ItemDetailsLookup mDetailsLookup;
+    private DocDetailsLookup mDetailsLookup;
     private SelectionMetadata mSelectionMetadata;
     private KeyInputHandler mKeyListener;
-    private @Nullable BandSelectionHelper mBandSelector;
     private @Nullable DragHoverListener mDragHoverListener;
     private IconHelper mIconHelper;
     private SwipeRefreshLayout mRefreshLayout;
@@ -172,22 +166,22 @@
     private DocumentClipper mClipper;
     private GridLayoutManager mLayout;
     private int mColumnCount = 1;  // This will get updated when layout changes.
+    private int mColumnUnit = 1;
 
     private float mLiveScale = 1.0f;
     private @ViewMode int mMode;
+    private int mAppBarHeight;
 
     private View mProgressBar;
 
     private DirectoryState mLocalState;
 
-    // Blocks loading/reloading of content while user is actively making selection.
-    private ContentLock mContentLock = new ContentLock();
-
-    private Runnable mBandSelectStartedCallback;
-
     // Note, we use !null to indicate that selection was restored (from rotation).
     // So don't fiddle with this field unless you've got the bigger picture in mind.
-    private @Nullable Selection mRestoredSelection = null;
+    private @Nullable Bundle mRestoredState;
+
+    // Blocks loading/reloading of content while user is actively making selection.
+    private ContentLock mContentLock = new ContentLock();
 
     private SortModel.UpdateListener mSortListener = (model, updateType) -> {
         // Only when sort order has changed do we need to trigger another loading.
@@ -198,6 +192,14 @@
 
     private final Runnable mOnDisplayStateChanged = this::onDisplayStateChanged;
 
+    private final ViewTreeObserver.OnPreDrawListener mToolbarPreDrawListener = () -> {
+        setPreDrawListener(false);
+        if (mAppBarHeight != getAppBarLayoutHeight()) {
+            updateLayout(mState.derivedMode);
+        }
+        return true;
+    };
+
     @Override
     public View onCreateView(
             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -219,9 +221,12 @@
 
         mRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh_layout);
         mRefreshLayout.setOnRefreshListener(this);
-        mRecView.setItemAnimator(new DirectoryItemAnimator(mActivity));
+        mRecView.setItemAnimator(new DirectoryItemAnimator());
 
         mInjector = mActivity.getInjector();
+        // Initially, this selection tracker (delegator) uses a dummy implementation, so it must be
+        // updated (reset) when necessary things are ready.
+        mSelectionMgr = mInjector.selectionMgr;
         mModel = mInjector.getModel();
         mModel.reset();
 
@@ -233,7 +238,7 @@
                     new DragHost<>(
                             mActivity,
                             DocumentsApplication.getDragAndDropManager(mActivity),
-                            mInjector.selectionMgr,
+                            mSelectionMgr,
                             mInjector.actions,
                             mActivity.getDisplayState(),
                             mInjector.dialogs,
@@ -253,7 +258,6 @@
 
     @Override
     public void onDestroyView() {
-        mSelectionMgr.clearSelection();
         mInjector.actions.unregisterDisplayStateChangedListener(mOnDisplayStateChanged);
 
         // Cancel any outstanding thumbnail requests
@@ -265,10 +269,7 @@
 
         mModel.removeUpdateListener(mModelUpdateListener);
         mModel.removeUpdateListener(mAdapter.getModelUpdateListener());
-
-        if (mBandSelector != null) {
-            mBandSelector.removeOnBandStartedListener(mBandSelectStartedCallback);
-        }
+        setPreDrawListener(false);
 
         super.onDestroyView();
     }
@@ -282,17 +283,12 @@
         // Read arguments when object created for the first time.
         // Restore state if fragment recreated.
         Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
+        mRestoredState = args;
 
         mLocalState = new DirectoryState();
         mLocalState.restore(args);
-
-        // Restore any selection we may have squirreled away in retained state.
-        @Nullable RetainedState retained = mActivity.getRetainedState();
-        if (retained != null && retained.hasSelection()) {
-            // We claim the selection for ourselves and null it out once used
-            // so we don't have a rando selection hanging around in RetainedState.
-            mRestoredSelection = retained.selection;
-            retained.selection = null;
+        if (mLocalState.mSelectionId == null) {
+            mLocalState.mSelectionId = Integer.toHexString(System.identityHashCode(mRecView));
         }
 
         mIconHelper = new IconHelper(mActivity, MODE_GRID);
@@ -321,37 +317,19 @@
         mModel.addUpdateListener(mAdapter.getModelUpdateListener());
         mModel.addUpdateListener(mModelUpdateListener);
 
-        SelectionPredicate selectionPredicate =
+        SelectionPredicate<String> selectionPredicate =
                 new DocsSelectionPredicate(mInjector.config, mState, mModel, mRecView);
 
-        mSelectionMgr = mInjector.getSelectionManager(mAdapter, selectionPredicate);
         mFocusManager = mInjector.getFocusManager(mRecView, mModel);
         mActions = mInjector.getActionHandler(mContentLock);
 
         mRecView.setAccessibilityDelegateCompat(
                 new AccessibilityEventRouter(mRecView,
-                        (View child) -> onAccessibilityClick(child)));
+                        (View child) -> onAccessibilityClick(child),
+                        (View child) -> onAccessibilityLongClick(child)));
         mSelectionMetadata = new SelectionMetadata(mModel::getItem);
-        mSelectionMgr.addObserver(mSelectionMetadata);
         mDetailsLookup = new DocsItemDetailsLookup(mRecView);
 
-        GestureSelectionHelper gestureHelper = GestureSelectionHelper.create(
-                mSelectionMgr, mRecView, mContentLock, mDetailsLookup);
-
-        if (mState.allowMultiple) {
-            mBandSelector = new BandSelectionHelper(
-                    new DefaultBandHost(mRecView, R.drawable.band_select_overlay),
-                    mAdapter,
-                    new DocsStableIdProvider(mAdapter),
-                    mSelectionMgr,
-                    selectionPredicate,
-                    new DefaultBandPredicate(mDetailsLookup),
-                    mContentLock);
-
-            mBandSelectStartedCallback = mFocusManager::clearFocus;
-            mBandSelector.addOnBandStartedListener(mBandSelectStartedCallback);
-        }
-
         DragStartListener dragStartListener = mInjector.config.dragAndDropEnabled()
                 ? DragStartListener.create(
                         mIconHelper,
@@ -359,12 +337,33 @@
                         mSelectionMgr,
                         mSelectionMetadata,
                         mState,
-                        mDetailsLookup,
                         this::getModelId,
                         mRecView::findChildViewUnder,
                         DocumentsApplication.getDragAndDropManager(mActivity))
                 : DragStartListener.DUMMY;
 
+        {
+            // Limiting the scope of the localTracker so nobody uses it.
+            // This block initializes/updates the global SelectionTracker held in mSelectionMgr.
+            SelectionTracker<String> localTracker = new SelectionTracker.Builder<>(
+                    mLocalState.mSelectionId,
+                    mRecView,
+                    new DocsStableIdProvider(mAdapter),
+                    mDetailsLookup,
+                    StorageStrategy.createStringStorage())
+                            .withBandOverlay(R.drawable.band_select_overlay)
+                            .withFocusDelegate(mFocusManager)
+                            .withOnDragInitiatedListener(dragStartListener::onDragEvent)
+                            .withOnContextClickListener(this::onContextMenuClick)
+                            .withOnItemActivatedListener(this::onItemActivated)
+                            .withOperationMonitor(mContentLock.getMonitor())
+                            .withSelectionPredicate(selectionPredicate)
+                            .build();
+            mInjector.updateSharedSelectionTracker(localTracker);
+        }
+
+        mSelectionMgr.addObserver(mSelectionMetadata);
+
         // Construction of the input handlers is non trivial, so to keep logic clear,
         // and code flexible, and DirectoryFragment small, the construction has been
         // moved off into a separate class.
@@ -372,25 +371,14 @@
                 mActions,
                 mSelectionMgr,
                 selectionPredicate,
-                mDetailsLookup,
                 mFocusManager,
-                mRecView,
-                mState);
-
-        MouseInputHandler mouseHandler =
-                handlers.createMouseHandler(this::onContextMenuClick);
-
-        TouchInputHandler touchHandler =
-                handlers.createTouchHandler(gestureHelper, dragStartListener);
-
-        GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>(touchHandler);
-        gestureRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mouseHandler);
+                mRecView);
 
         // This little guy gets added to each Holder, so that we can be notified of key events
         // on RecyclerView items.
         mKeyListener = handlers.createKeyHandler();
 
-        if (Build.IS_DEBUGGABLE) {
+        if (DEBUG) {
             new ScaleHelper(this.getContext(), mInjector.features, this::scaleLayout)
                     .attach(mRecView);
         }
@@ -398,17 +386,6 @@
         new RefreshHelper(mRefreshLayout::setEnabled)
                 .attach(mRecView);
 
-        GestureDetector gestureDetector = new GestureDetector(getContext(), gestureRouter);
-
-        TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector, gestureHelper);
-
-        eventRouter.register(
-                MotionEvent.TOOL_TYPE_MOUSE,
-                new MouseDragEventInterceptor(
-                        mDetailsLookup, dragStartListener::onMouseDragEvent, mBandSelector));
-
-        mRecView.addOnItemTouchListener(eventRouter);
-
         mActionModeController = mInjector.getActionModeController(
                 mSelectionMetadata,
                 this::handleMenuItemClick);
@@ -454,16 +431,12 @@
         mState.dirConfigs.put(mLocalState.getConfigKey(), container);
     }
 
-    public void retainState(RetainedState state) {
-        state.selection = new Selection();
-        mSelectionMgr.copySelection(state.selection);
-    }
-
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
 
         mLocalState.save(outState);
+        mSelectionMgr.onSaveInstanceState(outState);
     }
 
     @Override
@@ -494,7 +467,7 @@
 
         FileOperation operation = mLocalState.claimPendingOperation();
 
-        if (resultCode == Activity.RESULT_CANCELED || data == null) {
+        if (resultCode == FragmentActivity.RESULT_CANCELED || data == null) {
             // User pressed the back button or otherwise cancelled the destination pick. Don't
             // proceed with the copy.
             operation.dispose();
@@ -514,7 +487,7 @@
     // TODO: Move to UserInputHander.
     protected boolean onContextMenuClick(MotionEvent e) {
 
-        if (mDetailsLookup.overStableItem(e)) {
+        if (mDetailsLookup.overItemWithSelectionKey(e)) {
             View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
             ViewHolder holder = mRecView.getChildViewHolder(childView);
 
@@ -529,6 +502,17 @@
         return true;
     }
 
+    private boolean onItemActivated(ItemDetails<String> item, MotionEvent e) {
+        if (((DocumentItemDetails) item).inPreviewIconHotspot(e)) {
+            return mActions.previewItem(item);
+        }
+
+        return mActions.openItem(
+                item,
+                ActionHandler.VIEW_TYPE_PREVIEW,
+                ActionHandler.VIEW_TYPE_REGULAR);
+    }
+
     public void onViewModeChanged() {
         // Mode change is just visual change; no need to kick loader.
         onDisplayStateChanged();
@@ -551,12 +535,24 @@
         }
 
         int pad = getDirectoryPadding(mode);
-        mRecView.setPadding(pad, pad, pad, pad);
+        mAppBarHeight = getAppBarLayoutHeight();
+        mRecView.setPadding(pad, mAppBarHeight, pad, getSaveLayoutHeight());
         mRecView.requestLayout();
-        if (mBandSelector != null) {
-            mBandSelector.reset();
-        }
         mIconHelper.setViewMode(mode);
+
+        int range = getResources().getDimensionPixelOffset(R.dimen.refresh_icon_range);
+        mRefreshLayout.setProgressViewOffset(true, mAppBarHeight, mAppBarHeight + range);
+    }
+
+    private int getAppBarLayoutHeight() {
+        View appBarLayout = getActivity().findViewById(R.id.app_bar);
+        View collapsingBar = getActivity().findViewById(R.id.collapsing_toolbar);
+        return collapsingBar == null ? 0 : appBarLayout.getHeight();
+    }
+
+    private int getSaveLayoutHeight() {
+        View containerSave = getActivity().findViewById(R.id.container_save);
+        return containerSave == null ? 0 : containerSave.getHeight();
     }
 
     /**
@@ -564,7 +560,7 @@
      * @param mode The new view mode.
      */
     private void scaleLayout(float scale) {
-        assert Build.IS_DEBUGGABLE;
+        assert DEBUG;
 
         if (VERBOSE) Log.v(
                 TAG, "Handling scale event: " + scale + ", existing scale: " + mLiveScale);
@@ -578,13 +574,17 @@
                     "Next scale " + nextScale + ", Min/max scale " + minScale + "/" + maxScale);
 
             if (nextScale > minScale && nextScale < maxScale) {
-                if (DEBUG) Log.d(TAG, "Updating grid scale: " + scale);
+                if (DEBUG) {
+                    Log.d(TAG, "Updating grid scale: " + scale);
+                }
                 mLiveScale = nextScale;
                 updateLayout(mMode);
             }
 
         } else {
-            if (DEBUG) Log.d(TAG, "List mode, ignoring scale: " + scale);
+            if (DEBUG) {
+                Log.d(TAG, "List mode, ignoring scale: " + scale);
+            }
             mLiveScale = 1.0f;
         }
     }
@@ -602,7 +602,10 @@
 
         // RecyclerView sometimes gets a width of 0 (see b/27150284).
         // Clamp so that we always lay out the grid with at least 2 columns by default.
-        int columnCount = Math.max(2,
+        // If on photo picking state, the UI should show 3 images a row or 2 folders a row,
+        // so use 6 columns by default and set folder size to 3 and document size is to 2.
+        mColumnUnit = mState.isPhotoPicking() ? 3 : 1;
+        int columnCount = mColumnUnit * Math.max(2,
                 (mRecView.getWidth() - viewPadding) / (cellWidth + cellMargin));
 
         // Finally with our grid count logic firmly in place, we apply any live scaling
@@ -634,11 +637,14 @@
     }
 
     private boolean handleMenuItemClick(MenuItem item) {
-        Selection selection = new Selection();
+        if (mInjector.pickResult != null) {
+            mInjector.pickResult.increaseActionCount();
+        }
+        MutableSelection<String> selection = new MutableSelection<>();
         mSelectionMgr.copySelection(selection);
 
         switch (item.getItemId()) {
-            case R.id.action_menu_open:
+            case R.id.action_menu_select:
             case R.id.dir_menu_open:
                 openDocuments(selection);
                 mActionModeController.finishActionMode();
@@ -746,19 +752,43 @@
                 mActions.viewInOwner();
                 return true;
 
+            case R.id.action_menu_sort:
+                mActions.showSortDialog();
+                return true;
+
             default:
-                if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
+                if (DEBUG) {
+                    Log.d(TAG, "Unhandled menu item selected: " + item);
+                }
                 return false;
         }
     }
 
     private boolean onAccessibilityClick(View child) {
-        DocumentHolder holder = getDocumentHolder(child);
-        mActions.openItem(holder.getItemDetails(), ActionHandler.VIEW_TYPE_PREVIEW,
+        if (mSelectionMgr.hasSelection()) {
+            selectItem(child);
+        } else {
+            DocumentHolder holder = getDocumentHolder(child);
+            mActions.openItem(holder.getItemDetails(), ActionHandler.VIEW_TYPE_PREVIEW,
                 ActionHandler.VIEW_TYPE_REGULAR);
+        }
         return true;
     }
 
+    private boolean onAccessibilityLongClick(View child) {
+        selectItem(child);
+        return true;
+    }
+
+    private void selectItem(View child) {
+        final String id = getModelId(child);
+        if (mSelectionMgr.isSelected(id)) {
+            mSelectionMgr.deselect(id);
+        } else {
+            mSelectionMgr.select(id);
+        }
+    }
+
     private void cancelThumbnailTask(View view) {
         final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb);
         if (iconThumb != null) {
@@ -768,7 +798,7 @@
 
     // Support for opening multiple documents is currently exclusive to DocumentsActivity.
     private void openDocuments(final Selection selected) {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_OPEN);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_OPEN);
 
         // Model must be accessed in UI thread, since underlying cursor is not threadsafe.
         List<DocumentInfo> docs = mModel.getDocuments(selected);
@@ -779,8 +809,8 @@
         }
     }
 
-    private void showChooserForDoc(final Selection selected) {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_OPEN);
+    private void showChooserForDoc(final Selection<String> selected) {
+        Metrics.logUserAction(MetricConsts.USER_ACTION_OPEN);
 
         assert selected.size() == 1;
         DocumentInfo doc =
@@ -788,20 +818,21 @@
         mActions.showChooserForDoc(doc);
     }
 
-    private void transferDocuments(final Selection selected, @Nullable DocumentStack destination,
+    private void transferDocuments(
+            final Selection<String> selected, @Nullable DocumentStack destination,
             final @OpType int mode) {
         switch (mode) {
             case FileOperationService.OPERATION_COPY:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_TO);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_COPY_TO);
                 break;
             case FileOperationService.OPERATION_COMPRESS:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COMPRESS);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_COMPRESS);
                 break;
             case FileOperationService.OPERATION_EXTRACT:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_EXTRACT_TO);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_EXTRACT_TO);
                 break;
             case FileOperationService.OPERATION_MOVE:
-                Metrics.logUserAction(getContext(), Metrics.USER_ACTION_MOVE_TO);
+                Metrics.logUserAction(MetricConsts.USER_ACTION_MOVE_TO);
                 break;
         }
 
@@ -900,7 +931,7 @@
     }
 
     private void renameDocuments(Selection selected) {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_RENAME);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_RENAME);
 
         // Batch renaming not supported
         // Rename option is only available in menu when 1 document selected
@@ -919,7 +950,7 @@
      * Paste selection files from the primary clip into the current window.
      */
     public void pasteFromClipboard() {
-        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_PASTE_CLIPBOARD);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_PASTE_CLIPBOARD);
         // Since we are pasting into the current window, we already have the destination in the
         // stack. No need for a destination DocumentInfo.
         mClipper.copyFromClipboard(
@@ -997,9 +1028,26 @@
         return null;
     }
 
+    private void setPreDrawListener(boolean enable) {
+        if (mActivity == null) {
+            return;
+        }
+
+        final View bar = mActivity.findViewById(R.id.collapsing_toolbar);
+        if (bar != null) {
+            if (enable) {
+                bar.getViewTreeObserver().addOnPreDrawListener(mToolbarPreDrawListener);
+            } else {
+                bar.getViewTreeObserver().removeOnPreDrawListener(mToolbarPreDrawListener);
+            }
+        }
+    }
+
     public static void showDirectory(
             FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
-        if (DEBUG) Log.d(TAG, "Showing directory: " + DocumentInfo.debugString(doc));
+        if (DEBUG) {
+            Log.d(TAG, "Showing directory: " + DocumentInfo.debugString(doc));
+        }
         create(fm, root, doc, anim);
     }
 
@@ -1024,7 +1072,6 @@
         final Bundle args = new Bundle();
         args.putParcelable(Shared.EXTRA_ROOT, root);
         args.putParcelable(Shared.EXTRA_DOC, doc);
-        args.putParcelable(Shared.EXTRA_SELECTION, new Selection());
 
         final FragmentTransaction ft = fm.beginTransaction();
         AnimationView.setupAnimations(ft, anim, args);
@@ -1048,6 +1095,24 @@
         return R.id.container_directory;
     }
 
+    /**
+     *  Scroll to top of recyclerView in fragment
+     */
+    public void scrollToTop() {
+        if (mRecView != null) {
+            mRecView.scrollToPosition(0);
+        }
+    }
+
+    /**
+     *  Stop the scroll of recyclerView in fragment
+     */
+    public void stopScroll() {
+        if (mRecView != null) {
+            mRecView.stopScroll();
+        }
+    }
+
     @Override
     public void onRefresh() {
         // Remove thumbnail cache. We do this not because we're worried about stale thumbnails as it
@@ -1075,17 +1140,27 @@
 
         @Override
         public void accept(Model.Update update) {
-            if (DEBUG) Log.d(TAG, "Received model update. Loading=" + mModel.isLoading());
+            if (DEBUG) {
+                Log.d(TAG, "Received model update. Loading=" + mModel.isLoading());
+            }
 
             mProgressBar.setVisibility(mModel.isLoading() ? View.VISIBLE : View.GONE);
 
             updateLayout(mState.derivedMode);
 
+            // Update the selection to remove any disappeared IDs.
+            Iterator<String> selectionIter = mSelectionMgr.getSelection().iterator();
+            while (selectionIter.hasNext()) {
+                if (!mAdapter.getStableIds().contains(selectionIter.next())) {
+                    selectionIter.remove();
+                }
+            }
+
             mAdapter.notifyDataSetChanged();
 
-            if (mRestoredSelection != null) {
-                mSelectionMgr.restoreSelection(mRestoredSelection);
-                mRestoredSelection = null;
+            if (mRestoredState != null) {
+                mSelectionMgr.onRestoreInstanceState(mRestoredState);
+                mRestoredState = null;
             }
 
             // Restore any previous instance state
@@ -1095,8 +1170,10 @@
 
             final SortDimension curSortedDimension =
                     mState.sortModel.getDimensionById(curSortedDimensionId);
+
+            // Default not restore to avoid app bar layout expand to confuse users.
             if (container != null
-                    && !getArguments().getBoolean(Shared.EXTRA_IGNORE_STATE, false)) {
+                    && !getArguments().getBoolean(Shared.EXTRA_IGNORE_STATE, true)) {
                 getView().restoreHierarchyState(container);
             } else if (mLocalState.mLastSortDimensionId != curSortedDimension.getId()
                     || mLocalState.mLastSortDimensionId == SortModel.SORT_DIMENSION_ID_UNKNOWN
@@ -1117,10 +1194,14 @@
             if (!mModel.isLoading()) {
                 mActivity.notifyDirectoryLoaded(
                         mModel.doc != null ? mModel.doc.derivedUri : null);
-                if (mModel.doc == null) {
-                    // Invalid model, then update options menu to disable some items.
-                    mActivity.invalidateOptionsMenu();
-                }
+                // For orientation changed case, sometimes the docs loading comes after the menu
+                // update. We need to update the menu here to ensure the status is correct.
+                mInjector.menuManager.updateModel(mModel);
+                mInjector.menuManager.updateOptionMenu();
+
+                mActivity.updateHeaderTitle();
+
+                setPreDrawListener(true);
             }
         }
     }
diff --git a/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java b/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java
index d769f7f..626710e 100644
--- a/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java
+++ b/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java
@@ -20,9 +20,11 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.support.v4.util.ArrayMap;
-import android.support.v7.widget.DefaultItemAnimator;
-import android.support.v7.widget.RecyclerView;
+import androidx.collection.ArrayMap;
+import androidx.recyclerview.widget.DefaultItemAnimator;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.content.res.TypedArray;
 import android.util.TypedValue;
 
 import com.android.documentsui.R;
@@ -41,13 +43,6 @@
     private final List<ColorAnimation> mPendingAnimations = new ArrayList<>();
     private final Map<RecyclerView.ViewHolder, ColorAnimation> mRunningAnimations =
             new ArrayMap<>();
-    private final Integer mDefaultColor;
-    private final Integer mSelectedColor;
-
-    public DirectoryItemAnimator(Context context) {
-        mDefaultColor = context.getResources().getColor(R.color.item_doc_background);
-        mSelectedColor = context.getResources().getColor(R.color.item_doc_background_selected);
-    }
 
     @Override
     public void runPendingAnimations() {
diff --git a/src/com/android/documentsui/dirlist/DirectoryState.java b/src/com/android/documentsui/dirlist/DirectoryState.java
index b27a4b8..30d570c 100644
--- a/src/com/android/documentsui/dirlist/DirectoryState.java
+++ b/src/com/android/documentsui/dirlist/DirectoryState.java
@@ -22,8 +22,8 @@
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperationService;
-import com.android.documentsui.sorting.SortModel;
 import com.android.documentsui.sorting.SortDimension.SortDirection;
+import com.android.documentsui.sorting.SortModel;
 
 import javax.annotation.Nullable;
 
@@ -31,6 +31,7 @@
 
     private static final String EXTRA_SORT_DIMENSION_ID = "sortDimensionId";
     private static final String EXTRA_SORT_DIRECTION = "sortDirection";
+    private static final String EXTRA_SELECTION_ID = "selectionId";
 
     // Null when viewing Recents directory.
     @Nullable DocumentInfo mDocument;
@@ -40,6 +41,10 @@
     int mLastSortDimensionId = SortModel.SORT_DIMENSION_ID_UNKNOWN;
     @SortDirection int mLastSortDirection;
 
+    // The unique id to identify the selection. It is null when the corresponding
+    // container (fragment/activity) is the first launch.
+    @Nullable String mSelectionId;
+
     private RootInfo mRoot;
     private String mConfigKey;
 
@@ -49,6 +54,7 @@
         mPendingOperation = bundle.getParcelable(FileOperationService.EXTRA_OPERATION);
         mLastSortDimensionId = bundle.getInt(EXTRA_SORT_DIMENSION_ID);
         mLastSortDirection = bundle.getInt(EXTRA_SORT_DIRECTION);
+        mSelectionId = bundle.getString(EXTRA_SELECTION_ID);
     }
 
     public void save(Bundle bundle) {
@@ -57,6 +63,7 @@
         bundle.putParcelable(FileOperationService.EXTRA_OPERATION, mPendingOperation);
         bundle.putInt(EXTRA_SORT_DIMENSION_ID, mLastSortDimensionId);
         bundle.putInt(EXTRA_SORT_DIRECTION, mLastSortDirection);
+        bundle.putString(EXTRA_SELECTION_ID, mSelectionId);
     }
 
     public FileOperation claimPendingOperation() {
@@ -65,11 +72,6 @@
         return op;
     }
 
-    public void update(RootInfo root, DocumentInfo doc) {
-        mRoot = root;
-        mDocument = doc;
-    }
-
     String getConfigKey() {
         if (mConfigKey == null) {
             final StringBuilder builder = new StringBuilder();
diff --git a/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java b/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java
index a1f91a0..6f16b76 100644
--- a/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java
+++ b/src/com/android/documentsui/dirlist/DocsItemDetailsLookup.java
@@ -15,18 +15,19 @@
  */
 package com.android.documentsui.dirlist;
 
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.android.documentsui.selection.ItemDetailsLookup;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+
+import com.android.documentsui.DocsSelectionHelper.DocDetailsLookup;
 
 /**
  * Access to details of an item associated with a {@link MotionEvent} instance.
  */
-final class DocsItemDetailsLookup extends ItemDetailsLookup {
+final class DocsItemDetailsLookup extends DocDetailsLookup {
 
     private final RecyclerView mRecView;
 
@@ -35,47 +36,7 @@
     }
 
     @Override
-    public boolean overItem(MotionEvent e) {
-        return getItemPosition(e) != RecyclerView.NO_POSITION;
-    }
-
-    @Override
-    public boolean overStableItem(MotionEvent e) {
-    if (!overItem(e)) {
-        return false;
-    }
-    ItemDetails details = getItemDetails(e);
-    return details != null && details.hasStableId();
-    }
-
-    @Override
-    public boolean inItemDragRegion(MotionEvent e) {
-    if (!overItem(e)) {
-        return false;
-    }
-    ItemDetails details = getItemDetails(e);
-    return details != null && details.inDragRegion(e);
-    }
-
-    @Override
-    public boolean inItemSelectRegion(MotionEvent e) {
-    if (!overItem(e)) {
-        return false;
-    }
-    ItemDetails details = getItemDetails(e);
-    return details != null && details.inSelectionHotspot(e);
-    }
-
-    @Override
-    public int getItemPosition(MotionEvent e) {
-        View child = mRecView.findChildViewUnder(e.getX(), e.getY());
-        return (child != null)
-                ? mRecView.getChildAdapterPosition(child)
-                : RecyclerView.NO_POSITION;
-    }
-
-    @Override
-    public ItemDetails getItemDetails(MotionEvent e) {
+    public DocumentItemDetails getItemDetails(MotionEvent e) {
         @Nullable DocumentHolder holder = getDocumentHolder(e);
         return holder == null ? null : holder.getItemDetails();
     }
diff --git a/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java b/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java
index 679bd9f..f7b8122 100644
--- a/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java
+++ b/src/com/android/documentsui/dirlist/DocsSelectionPredicate.java
@@ -15,25 +15,27 @@
  */
 package com.android.documentsui.dirlist;
 
-import static android.support.v4.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
+
 import static com.android.documentsui.base.DocumentInfo.getCursorInt;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 
 import android.database.Cursor;
 import android.provider.DocumentsContract.Document;
-import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 
+import androidx.recyclerview.selection.SelectionTracker.SelectionPredicate;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.documentsui.ActivityConfig;
 import com.android.documentsui.Model;
 import com.android.documentsui.base.State;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
 
 /**
  * Class embodying the logic as to whether an item (specified by id or position)
  * can be selected (or not).
  */
-final class DocsSelectionPredicate extends SelectionPredicate {
+final class DocsSelectionPredicate extends SelectionPredicate<String> {
 
     private ActivityConfig mConfig;
     private Model mModel;
@@ -56,7 +58,7 @@
     }
 
     @Override
-    public boolean canSetStateForId(String id, boolean nextState) {
+    public boolean canSetStateForKey(String id, boolean nextState) {
         if (nextState) {
             // Check if an item can be selected
             final Cursor cursor = mModel.getItem(id);
@@ -88,8 +90,12 @@
 
         // The band selection model only operates on documents and directories.
         // Exclude other types of adapter items like whitespace and dividers.
-        RecyclerView.ViewHolder vh = mRecView.findViewHolderForAdapterPosition(position);
-        return ModelBackedDocumentsAdapter.isContentType(vh.getItemViewType());
+        final RecyclerView.ViewHolder vh = mRecView.findViewHolderForAdapterPosition(position);
+        if (vh == null) {
+            return false;
+        } else {
+            return ModelBackedDocumentsAdapter.isContentType(vh.getItemViewType());
+        }
     }
 
     @Override
diff --git a/src/com/android/documentsui/dirlist/DocsStableIdProvider.java b/src/com/android/documentsui/dirlist/DocsStableIdProvider.java
index 889b82a..6ff73f2 100644
--- a/src/com/android/documentsui/dirlist/DocsStableIdProvider.java
+++ b/src/com/android/documentsui/dirlist/DocsStableIdProvider.java
@@ -15,11 +15,9 @@
  */
 package com.android.documentsui.dirlist;
 
-import static android.support.v4.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
-
-import java.util.List;
+import com.android.documentsui.DocsSelectionHelper.StableIdProvider;
 
 /**
  * Provides RecyclerView selection code access to stable ids backed
@@ -35,7 +33,7 @@
     }
 
     @Override
-    public String getStableId(int position) {
+    public String getKey(int position) {
         return mAdapter.getStableId(position);
     }
 
@@ -43,9 +41,4 @@
     public int getPosition(String id) {
         return mAdapter.getPosition(id);
     }
-
-    @Override
-    public List<String> getStableIds() {
-        return mAdapter.getStableIds();
-    }
 }
diff --git a/src/com/android/documentsui/dirlist/DocumentHolder.java b/src/com/android/documentsui/dirlist/DocumentHolder.java
index a412e72..263c586 100644
--- a/src/com/android/documentsui/dirlist/DocumentHolder.java
+++ b/src/com/android/documentsui/dirlist/DocumentHolder.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 import android.database.Cursor;
-import android.support.v7.widget.RecyclerView;
+import android.os.Bundle;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -27,11 +27,19 @@
 import android.view.ViewPropertyAnimator;
 import android.widget.ImageView;
 
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.documentsui.base.Shared;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import com.android.documentsui.base.State;
+
+import java.util.function.Function;
 
 import javax.annotation.Nullable;
 
+/**
+ * ViewHolder of a document item within a RecyclerView.
+ */
 public abstract class DocumentHolder
         extends RecyclerView.ViewHolder implements View.OnKeyListener {
 
@@ -41,8 +49,10 @@
 
     protected @Nullable String mModelId;
 
+    protected @State.ActionType int mAction;
+
     // See #addKeyEventListener for details on the need for this field.
-    private KeyboardEventListener mKeyEventListener;
+    private KeyboardEventListener<DocumentItemDetails> mKeyEventListener;
 
     private final DocumentItemDetails mDetails;
 
@@ -56,7 +66,7 @@
         itemView.setOnKeyListener(this);
 
         mContext = context;
-        mDetails = new DocumentItemDetails();
+        mDetails = new DocumentItemDetails(this);
     }
 
     /**
@@ -91,13 +101,19 @@
         setEnabledRecursive(itemView, enabled);
     }
 
+    public void setAction(@State.ActionType int action) {
+        mAction = action;
+    }
+
+    public void bindPreviewIcon(boolean show, Function<View, Boolean> clickCallback) {}
+
     @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         assert(mKeyEventListener != null);
-        ItemDetails details = getItemDetails();
+        DocumentItemDetails details = getItemDetails();
         return (details == null)
-            ? false
-            : mKeyEventListener.onKey(getItemDetails(),  keyCode,  event);
+                ? false
+                : mKeyEventListener.onKey(details, keyCode, event);
     }
 
     /**
@@ -108,7 +124,7 @@
      *
      * <p>Ideally we'd not involve DocumentHolder in propagation of events like this.
      */
-    public void addKeyEventListener(KeyboardEventListener listener) {
+    public void addKeyEventListener(KeyboardEventListener<DocumentItemDetails> listener) {
         assert(mKeyEventListener == null);
         mKeyEventListener = listener;
     }
@@ -121,7 +137,11 @@
         return false;
     }
 
-    public ItemDetails getItemDetails() {
+    public boolean inPreviewIconRegion(MotionEvent event) {
+        return false;
+    }
+
+    public DocumentItemDetails getItemDetails() {
         return mDetails;
     }
 
@@ -149,31 +169,20 @@
         return view.animate().setDuration(Shared.CHECK_ANIMATION_DURATION).alpha(alpha);
     }
 
-    private final class DocumentItemDetails extends ItemDetails {
+    protected static class PreviewAccessibilityDelegate extends View.AccessibilityDelegate {
+        private Function<View, Boolean> mCallback;
 
-        @Override
-        public int getPosition() {
-            return DocumentHolder.this.getAdapterPosition();
+        public PreviewAccessibilityDelegate(Function<View, Boolean> clickCallback) {
+            super();
+            mCallback = clickCallback;
         }
 
         @Override
-        public String getStableId() {
-            return DocumentHolder.this.getModelId();
-        }
-
-        @Override
-        public int getItemViewType() {
-            return DocumentHolder.this.getItemViewType();
-        }
-
-        @Override
-        public boolean inDragRegion(MotionEvent e) {
-            return DocumentHolder.this.inDragRegion(e);
-        }
-
-        @Override
-        public boolean inSelectionHotspot(MotionEvent e) {
-            return DocumentHolder.this.inSelectRegion(e);
+        public boolean performAccessibilityAction(View host, int action, Bundle args) {
+            if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
+                return mCallback.apply(host);
+            }
+            return super.performAccessibilityAction(host, action, args);
         }
     }
 }
diff --git a/src/com/android/documentsui/dirlist/DocumentItemDetails.java b/src/com/android/documentsui/dirlist/DocumentItemDetails.java
new file mode 100644
index 0000000..ab86448
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/DocumentItemDetails.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 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.documentsui.dirlist;
+
+import android.view.MotionEvent;
+
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+
+/**
+ * Provide information of a specific RecyclerView item for selection.
+ */
+public final class DocumentItemDetails extends ItemDetails<String> {
+    private final DocumentHolder mDocumentHolder;
+
+    DocumentItemDetails(DocumentHolder holder) {
+        mDocumentHolder = holder;
+    }
+
+    /**
+     * @return The view type of this ViewHolder.
+     */
+    public int getItemViewType() {
+        return mDocumentHolder.getItemViewType();
+    }
+
+    @Override
+    public int getPosition() {
+        return mDocumentHolder.getAdapterPosition();
+    }
+
+    @Override
+    public String getSelectionKey() {
+        return mDocumentHolder.getModelId();
+    }
+
+    @Override
+    public boolean inDragRegion(MotionEvent e) {
+        return mDocumentHolder.inDragRegion(e);
+    }
+
+    @Override
+    public boolean inSelectionHotspot(MotionEvent e) {
+        return mDocumentHolder.inSelectRegion(e);
+    }
+
+    public boolean inPreviewIconHotspot(MotionEvent e) {
+        return mDocumentHolder.inPreviewIconRegion(e);
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/DocumentsAdapter.java b/src/com/android/documentsui/dirlist/DocumentsAdapter.java
index f940814..a733f81 100644
--- a/src/com/android/documentsui/dirlist/DocumentsAdapter.java
+++ b/src/com/android/documentsui/dirlist/DocumentsAdapter.java
@@ -21,8 +21,8 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.provider.DocumentsContract.Document;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.documentsui.ActionHandler;
 import com.android.documentsui.Model;
diff --git a/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java b/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java
index b5c1806..a196364 100644
--- a/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java
+++ b/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java
@@ -18,20 +18,22 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.support.annotation.ColorRes;
-import android.support.v4.widget.SwipeRefreshLayout;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.MotionEvent;
 
+import androidx.annotation.ColorRes;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import com.android.documentsui.R;
+
 /**
  * A {@link SwipeRefreshLayout} that does not intercept any touch events. This relies on its nested
  * view to scroll in order to cause a refresh. It is possible that it gets disabled by
  * {@link ListeningGestureDetector} .
  */
 public class DocumentsSwipeRefreshLayout extends SwipeRefreshLayout {
-
-    private static final int[] COLOR_RES = new int[] { android.R.attr.colorAccent };
-    private static int COLOR_ACCENT_INDEX = 0;
+    private static final String TAG = DocumentsSwipeRefreshLayout.class.getSimpleName();
 
     public DocumentsSwipeRefreshLayout(Context context) {
         this(context, null);
@@ -40,8 +42,14 @@
     public DocumentsSwipeRefreshLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        TypedArray a = context.obtainStyledAttributes(COLOR_RES);
-        @ColorRes int colorId = a.getResourceId(COLOR_ACCENT_INDEX, -1);
+        final int[] styledAttrs = {android.R.attr.colorPrimary};
+
+        TypedArray a = context.obtainStyledAttributes(styledAttrs);
+        @ColorRes int colorId = a.getResourceId(0, -1);
+        if (colorId == -1) {
+            Log.w(TAG, "Retrive colorPrimary colorId from theme fail, assign R.color.primary");
+            colorId = R.color.primary;
+        }
         a.recycle();
         setColorSchemeResources(colorId);
     }
diff --git a/src/com/android/documentsui/dirlist/DragHost.java b/src/com/android/documentsui/dirlist/DragHost.java
index 770097d..b08637b 100644
--- a/src/com/android/documentsui/dirlist/DragHost.java
+++ b/src/com/android/documentsui/dirlist/DragHost.java
@@ -20,9 +20,11 @@
 
 import android.app.Activity;
 import android.content.ClipData;
+import android.util.Log;
 import android.view.DragEvent;
 import android.view.View;
-import android.util.Log;
+
+import androidx.recyclerview.selection.SelectionTracker;
 
 import com.android.documentsui.AbstractActionHandler;
 import com.android.documentsui.AbstractDragHost;
@@ -32,7 +34,6 @@
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.State;
-import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.ui.DialogController;
 
 import java.util.function.Predicate;
@@ -45,7 +46,7 @@
     private static final String TAG = "dirlist.DragHost";
 
     private final T mActivity;
-    private final SelectionHelper mSelectionMgr;
+    private final SelectionTracker<String> mSelectionMgr;
     private final ActionHandler mActions;
     private final State mState;
     private final DialogController mDialogs;
@@ -56,7 +57,7 @@
     DragHost(
             T activity,
             DragAndDropManager dragAndDropManager,
-            SelectionHelper selectionMgr,
+            SelectionTracker<String> selectionMgr,
             ActionHandler actions,
             State state,
             DialogController dialogs,
@@ -117,7 +118,9 @@
 
         DocumentInfo dst = mDestinationLookup.lookup(v);
         if (dst == null) {
-            if (DEBUG) Log.d(TAG, "Invalid destination. Ignoring.");
+            if (DEBUG) {
+                Log.d(TAG, "Invalid destination. Ignoring.");
+            }
             return false;
         }
 
diff --git a/src/com/android/documentsui/dirlist/DragStartListener.java b/src/com/android/documentsui/dirlist/DragStartListener.java
index e2859fc..8fe0872 100644
--- a/src/com/android/documentsui/dirlist/DragStartListener.java
+++ b/src/com/android/documentsui/dirlist/DragStartListener.java
@@ -17,24 +17,23 @@
 package com.android.documentsui.dirlist;
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.net.Uri;
-import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.Selection;
+import androidx.recyclerview.selection.SelectionTracker;
+
 import com.android.documentsui.DragAndDropManager;
 import com.android.documentsui.MenuManager.SelectionDetails;
 import com.android.documentsui.Model;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Events;
 import com.android.documentsui.base.State;
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.MutableSelection;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -51,17 +50,12 @@
 
     static final DragStartListener DUMMY = new DragStartListener() {
         @Override
-        public boolean onMouseDragEvent(MotionEvent event) {
-            return false;
-        }
-        @Override
-        public boolean onTouchDragEvent(MotionEvent event) {
+        public boolean onDragEvent(MotionEvent event) {
             return false;
         }
     };
 
-    boolean onMouseDragEvent(MotionEvent event);
-    boolean onTouchDragEvent(MotionEvent event);
+    boolean onDragEvent(MotionEvent event);
 
     @VisibleForTesting
     class RuntimeDragStartListener implements DragStartListener {
@@ -70,12 +64,11 @@
 
         private final IconHelper mIconHelper;
         private final State mState;
-        private final ItemDetailsLookup mDetailsLookup;
-        private final SelectionHelper mSelectionMgr;
+        private final SelectionTracker<String> mSelectionMgr;
         private final SelectionDetails mSelectionDetails;
         private final ViewFinder mViewFinder;
         private final Function<View, String> mIdFinder;
-        private final Function<Selection, List<DocumentInfo>> mDocsConverter;
+        private final Function<Selection<String>, List<DocumentInfo>> mDocsConverter;
         private final DragAndDropManager mDragAndDropManager;
 
 
@@ -84,17 +77,15 @@
         public RuntimeDragStartListener(
                 IconHelper iconHelper,
                 State state,
-                ItemDetailsLookup detailsLookup,
-                SelectionHelper selectionMgr,
+                SelectionTracker<String> selectionMgr,
                 SelectionDetails selectionDetails,
                 ViewFinder viewFinder,
                 Function<View, String> idFinder,
-                Function<Selection, List<DocumentInfo>> docsConverter,
+                Function<Selection<String>, List<DocumentInfo>> docsConverter,
                 DragAndDropManager dragAndDropManager) {
 
             mIconHelper = iconHelper;
             mState = state;
-            mDetailsLookup = detailsLookup;
             mSelectionMgr = selectionMgr;
             mSelectionDetails = selectionDetails;
             mViewFinder = viewFinder;
@@ -104,15 +95,7 @@
         }
 
         @Override
-        public final boolean onMouseDragEvent(MotionEvent event) {
-            checkArgument(Events.isMouseDragEvent(event));
-            checkArgument(mDetailsLookup.inItemDragRegion(event));
-
-            return startDrag(mViewFinder.findView(event.getX(), event.getY()), event);
-        }
-
-        @Override
-        public final boolean onTouchDragEvent(MotionEvent event) {
+        public final boolean onDragEvent(MotionEvent event) {
             return startDrag(mViewFinder.findView(event.getX(), event.getY()), event);
         }
 
@@ -122,17 +105,21 @@
         private boolean startDrag(@Nullable View view, MotionEvent event) {
 
             if (view == null) {
-                if (DEBUG) Log.d(TAG, "Ignoring drag event, null view.");
+                if (DEBUG) {
+                    Log.d(TAG, "Ignoring drag event, null view.");
+                }
                 return false;
             }
 
             @Nullable String modelId = mIdFinder.apply(view);
             if (modelId == null) {
-                if (DEBUG) Log.d(TAG, "Ignoring drag on view not represented in model.");
+                if (DEBUG) {
+                    Log.d(TAG, "Ignoring drag on view not represented in model.");
+                }
                 return false;
             }
 
-            Selection selection = getSelectionToBeCopied(modelId, event);
+            Selection<String> selection = getSelectionToBeCopied(modelId, event);
 
             final List<DocumentInfo> srcs = mDocsConverter.apply(selection);
 
@@ -158,8 +145,8 @@
          * coordinates of the event, return a valid selection for drag and drop operation
          */
         @VisibleForTesting
-        MutableSelection getSelectionToBeCopied(String modelId, MotionEvent event) {
-            MutableSelection selection = new MutableSelection();
+        MutableSelection<String> getSelectionToBeCopied(String modelId, MotionEvent event) {
+            MutableSelection<String> selection = new MutableSelection<>();
             // If CTRL-key is held down and there's other existing selection, add item to
             // selection (if not already selected)
             if (Events.isCtrlKeyPressed(event)
@@ -181,10 +168,9 @@
     static DragStartListener create(
             IconHelper iconHelper,
             Model model,
-            SelectionHelper selectionMgr,
+            SelectionTracker<String> selectionMgr,
             SelectionDetails selectionDetails,
             State state,
-            ItemDetailsLookup detailsLookup,
             Function<View, String> idFinder,
             ViewFinder viewFinder,
             DragAndDropManager dragAndDropManager) {
@@ -192,7 +178,6 @@
         return new RuntimeDragStartListener(
                 iconHelper,
                 state,
-                detailsLookup,
                 selectionMgr,
                 selectionDetails,
                 viewFinder,
diff --git a/src/com/android/documentsui/dirlist/FocusHandler.java b/src/com/android/documentsui/dirlist/FocusHandler.java
index 23d53a9..2c7f8e6 100644
--- a/src/com/android/documentsui/dirlist/FocusHandler.java
+++ b/src/com/android/documentsui/dirlist/FocusHandler.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.dirlist;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.view.KeyEvent;
 import android.view.View;
 
@@ -62,7 +62,7 @@
     /**
      * @return The adapter position of the last focused item.
      */
-    int getFocusPosition();
+    int getFocusedPosition();
 
     /**
      * @return True if there is currently an item in focus, false otherwise.
diff --git a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
index 5d02957..e32a48b 100644
--- a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
+++ b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
@@ -20,14 +20,18 @@
 
 import android.content.Context;
 import android.database.Cursor;
-import android.graphics.Rect;
+import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.documentsui.IconUtils;
 import com.android.documentsui.R;
+import com.android.documentsui.base.State;
+import com.android.documentsui.ui.Views;
 
 final class GridDirectoryHolder extends DocumentHolder {
 
@@ -35,13 +39,17 @@
 
     private final ImageView mIconCheck;
     private final ImageView mIconMime;
+    private final View mIconLayout;
 
     public GridDirectoryHolder(Context context, ViewGroup parent) {
         super(context, parent, R.layout.item_dir_grid);
 
+        mIconLayout = itemView.findViewById(R.id.icon);
         mTitle = (TextView) itemView.findViewById(android.R.id.title);
         mIconMime = (ImageView) itemView.findViewById(R.id.icon_mime_sm);
         mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check);
+        mIconMime.setImageDrawable(
+                IconUtils.loadMimeIcon(context, DocumentsContract.Document.MIME_TYPE_DIR));
     }
 
     @Override
@@ -66,10 +74,7 @@
 
     @Override
     public boolean inSelectRegion(MotionEvent event) {
-        Rect iconRect = new Rect();
-        mIconMime.getGlobalVisibleRect(iconRect);
-
-        return iconRect.contains((int) event.getRawX(), (int) event.getRawY());
+        return mAction == State.ACTION_BROWSE ? Views.isEventOver(event, mIconLayout) : false;
     }
 
     /**
diff --git a/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/src/com/android/documentsui/dirlist/GridDocumentHolder.java
index 95be1b9..e27d210 100644
--- a/src/com/android/documentsui/dirlist/GridDocumentHolder.java
+++ b/src/com/android/documentsui/dirlist/GridDocumentHolder.java
@@ -19,10 +19,10 @@
 import static com.android.documentsui.base.DocumentInfo.getCursorLong;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 
-import android.annotation.ColorInt;
+import androidx.annotation.ColorInt;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.database.Cursor;
-import android.graphics.Rect;
 import android.provider.DocumentsContract.Document;
 import android.text.format.Formatter;
 import android.view.MotionEvent;
@@ -35,6 +35,9 @@
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.roots.RootCursorWrapper;
+import com.android.documentsui.ui.Views;
+
+import java.util.function.Function;
 
 final class GridDocumentHolder extends DocumentHolder {
 
@@ -46,18 +49,16 @@
     final ImageView mIconThumb;
     final ImageView mIconCheck;
     final IconHelper mIconHelper;
+    final View mIconLayout;
+    final View mPreviewIcon;
 
-    private final @ColorInt int mDisabledBgColor;
-    private final @ColorInt int mDefaultBgColor;
     // This is used in as a convenience in our bind method.
     private final DocumentInfo mDoc = new DocumentInfo();
 
     public GridDocumentHolder(Context context, ViewGroup parent, IconHelper iconHelper) {
         super(context, parent, R.layout.item_doc_grid);
 
-        mDisabledBgColor = context.getColor(R.color.item_doc_background_disabled);
-        mDefaultBgColor = context.getColor(R.color.item_doc_background);
-
+        mIconLayout = itemView.findViewById(R.id.icon);
         mTitle = (TextView) itemView.findViewById(android.R.id.title);
         mDate = (TextView) itemView.findViewById(R.id.date);
         mDetails = (TextView) itemView.findViewById(R.id.details);
@@ -65,6 +66,7 @@
         mIconMimeSm = (ImageView) itemView.findViewById(R.id.icon_mime_sm);
         mIconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb);
         mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check);
+        mPreviewIcon = itemView.findViewById(R.id.preview_icon);
 
         mIconHelper = iconHelper;
     }
@@ -101,8 +103,6 @@
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
 
-        // Text colors enabled/disabled is handle via a color set.
-        itemView.setBackgroundColor(enabled ? mDefaultBgColor : mDisabledBgColor);
         float imgAlpha = enabled ? 1f : DISABLED_ALPHA;
 
         mIconMimeLg.setAlpha(imgAlpha);
@@ -111,6 +111,16 @@
     }
 
     @Override
+    public void bindPreviewIcon(boolean show, Function<View, Boolean> clickCallback) {
+        mPreviewIcon.setVisibility(show ? View.VISIBLE : View.GONE);
+        if (show) {
+            mPreviewIcon.setContentDescription(
+                    itemView.getResources().getString(R.string.preview_file, mDoc.displayName));
+            mPreviewIcon.setAccessibilityDelegate(new PreviewAccessibilityDelegate(clickCallback));
+        }
+    }
+
+    @Override
     public boolean inDragRegion(MotionEvent event) {
      // Entire grid box should be draggable
         return true;
@@ -118,10 +128,12 @@
 
     @Override
     public boolean inSelectRegion(MotionEvent event) {
-        Rect iconRect = new Rect();
-        mIconMimeSm.getGlobalVisibleRect(iconRect);
+        return Views.isEventOver(event, mIconLayout);
+    }
 
-        return iconRect.contains((int) event.getRawX(), (int) event.getRawY());
+    @Override
+    public boolean inPreviewIconRegion(MotionEvent event) {
+        return Views.isEventOver(event, mPreviewIcon);
     }
 
     /**
diff --git a/src/com/android/documentsui/dirlist/GridPhotoHolder.java b/src/com/android/documentsui/dirlist/GridPhotoHolder.java
new file mode 100644
index 0000000..5a5feec
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/GridPhotoHolder.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2018 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.documentsui.dirlist;
+
+import static com.android.documentsui.base.DocumentInfo.getCursorLong;
+import static com.android.documentsui.base.DocumentInfo.getCursorString;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.DocumentsContract.Document;
+import android.text.format.Formatter;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.android.documentsui.R;
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.roots.RootCursorWrapper;
+import com.android.documentsui.ui.Views;
+
+import java.util.function.Function;
+
+final class GridPhotoHolder extends DocumentHolder {
+
+    private final ImageView mIconMimeLg;
+    private final ImageView mIconThumb;
+    private final ImageView mIconCheck;
+    private final IconHelper mIconHelper;
+    private final View mPreviewIcon;
+
+    // This is used in as a convenience in our bind method.
+    private final DocumentInfo mDoc = new DocumentInfo();
+
+    public GridPhotoHolder(Context context, ViewGroup parent, IconHelper iconHelper) {
+        super(context, parent, R.layout.item_photo_grid);
+
+        mIconMimeLg = (ImageView) itemView.findViewById(R.id.icon_mime_lg);
+        mIconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb);
+        mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check);
+        mPreviewIcon = itemView.findViewById(R.id.preview_icon);
+
+        mIconHelper = iconHelper;
+    }
+
+    @Override
+    public void setSelected(boolean selected, boolean animate) {
+        // We always want to make sure our check box disappears if we're not selected,
+        // even if the item is disabled. This is because this object can be reused
+        // and this method will be called to setup initial state.
+        float checkAlpha = selected ? 1f : 0f;
+        if (animate) {
+            fade(mIconCheck, checkAlpha).start();
+        } else {
+            mIconCheck.setAlpha(checkAlpha);
+        }
+
+        // But it should be an error to be set to selected && be disabled.
+        if (!itemView.isEnabled()) {
+            assert (!selected);
+            return;
+        }
+
+        super.setSelected(selected, animate);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+
+        float imgAlpha = enabled ? 1f : DISABLED_ALPHA;
+
+        mIconMimeLg.setAlpha(imgAlpha);
+        mIconThumb.setAlpha(imgAlpha);
+    }
+
+    @Override
+    public void bindPreviewIcon(boolean show, Function<View, Boolean> clickCallback) {
+        mPreviewIcon.setVisibility(show ? View.VISIBLE : View.GONE);
+        if (show) {
+            mPreviewIcon.setContentDescription(
+                    itemView.getResources().getString(R.string.preview_file, mDoc.displayName));
+            mPreviewIcon.setAccessibilityDelegate(new PreviewAccessibilityDelegate(clickCallback));
+        }
+    }
+
+    @Override
+    public boolean inDragRegion(MotionEvent event) {
+        // Entire grid box should be draggable
+        return true;
+    }
+
+    @Override
+    public boolean inSelectRegion(MotionEvent event) {
+        // Photo gird should not have any select region.
+        return false;
+    }
+
+    @Override
+    public boolean inPreviewIconRegion(MotionEvent event) {
+        return Views.isEventOver(event, mPreviewIcon);
+    }
+
+    /**
+     * Bind this view to the given document for display.
+     * @param cursor Pointing to the item to be bound.
+     * @param modelId The model ID of the item.
+     */
+    @Override
+    public void bind(Cursor cursor, String modelId) {
+        assert (cursor != null);
+
+        mModelId = modelId;
+
+        mDoc.updateFromCursor(cursor, getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY));
+
+        mIconHelper.stopLoading(mIconThumb);
+
+        mIconMimeLg.animate().cancel();
+        mIconMimeLg.setAlpha(1f);
+        mIconThumb.animate().cancel();
+        mIconThumb.setAlpha(0f);
+
+        mIconHelper.load(mDoc, mIconThumb, mIconMimeLg, null);
+
+        final String docSize =
+                Formatter.formatFileSize(mContext, getCursorLong(cursor, Document.COLUMN_SIZE));
+        final String docDate = Shared.formatTime(mContext, mDoc.lastModified);
+        itemView.setContentDescription(mDoc.displayName + ", " + docSize + ", " + docDate);
+    }
+}
diff --git a/src/com/android/documentsui/dirlist/IconHelper.java b/src/com/android/documentsui/dirlist/IconHelper.java
index c5e86c1..08b4f9f 100644
--- a/src/com/android/documentsui/dirlist/IconHelper.java
+++ b/src/com/android/documentsui/dirlist/IconHelper.java
@@ -27,11 +27,12 @@
 import android.net.Uri;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
 import android.util.Log;
 import android.view.View;
 import android.widget.ImageView;
 
+import androidx.annotation.Nullable;
+
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.IconUtils;
 import com.android.documentsui.ProviderExecutor;
@@ -45,7 +46,6 @@
 import com.android.documentsui.base.State.ViewMode;
 
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
 
 /**
  * A class to assist with loading and managing the Images (i.e. thumbnails and icons) associated
@@ -200,18 +200,14 @@
                         (cachedThumbnail == null ? ThumbnailLoader.ANIM_FADE_IN :
                                 ThumbnailLoader.ANIM_NO_OP);
 
-                Consumer<Bitmap> callback = new Consumer<Bitmap>() {
-                    @Override
-                    public void accept(Bitmap bitmap) {
-                        if (result != null) {
-                            iconThumb.setImageBitmap(bitmap);
-                            animator.accept(iconMime, iconThumb);
-                        }
-                    }
-                };
-
                 final ThumbnailLoader task = new ThumbnailLoader(uri, iconThumb,
-                    mCurrentSize, docLastModified, callback, true);
+                        mCurrentSize, docLastModified,
+                        bitmap -> {
+                            if (bitmap != null) {
+                                iconThumb.setImageBitmap(bitmap);
+                                animator.accept(iconMime, iconThumb);
+                            }
+                        }, true /* addToCache */);
 
                 ProviderExecutor.forAuthority(docAuthority).execute(task);
             }
diff --git a/src/com/android/documentsui/dirlist/InputHandlers.java b/src/com/android/documentsui/dirlist/InputHandlers.java
index 43143d4..8cc2bfb 100644
--- a/src/com/android/documentsui/dirlist/InputHandlers.java
+++ b/src/com/android/documentsui/dirlist/InputHandlers.java
@@ -15,24 +15,16 @@
  */
 package com.android.documentsui.dirlist;
 
-import static android.support.v4.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
+
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.SelectionTracker.SelectionPredicate;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.documentsui.ActionHandler;
-import com.android.documentsui.base.EventHandler;
-import com.android.documentsui.base.State;
-import com.android.documentsui.selection.GestureSelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.MouseInputHandler;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.TouchInputHandler;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
 
 /**
  * Helper class dedicated to building gesture input handlers. The construction
@@ -43,43 +35,36 @@
 final class InputHandlers {
 
     private ActionHandler mActions;
-    private SelectionHelper mSelectionHelper;
-    private SelectionPredicate mSelectionPredicate;
-    private ItemDetailsLookup mDetailsLookup;
+    private SelectionTracker<String> mSelectionHelper;
+    private SelectionPredicate<String> mSelectionPredicate;
     private FocusHandler mFocusHandler;
     private RecyclerView mRecView;
-    private State mState;
 
     InputHandlers(
             ActionHandler actions,
-            SelectionHelper selectionHelper,
-            SelectionPredicate selectionPredicate,
-            ItemDetailsLookup detailsLookup,
+            SelectionTracker<String> selectionHelper,
+            SelectionPredicate<String> selectionPredicate,
             FocusHandler focusHandler,
-            RecyclerView recView,
-            State state) {
+            RecyclerView recView) {
 
         checkArgument(actions != null);
         checkArgument(selectionHelper != null);
         checkArgument(selectionPredicate != null);
-        checkArgument(detailsLookup != null);
         checkArgument(focusHandler != null);
         checkArgument(recView != null);
-        checkArgument(state != null);
 
         mActions = actions;
         mSelectionHelper = selectionHelper;
         mSelectionPredicate = selectionPredicate;
-        mDetailsLookup = detailsLookup;
         mFocusHandler = focusHandler;
         mRecView = recView;
-        mState = state;
     }
 
     KeyInputHandler createKeyHandler() {
-        KeyInputHandler.Callbacks callbacks = new KeyInputHandler.Callbacks() {
+        KeyInputHandler.Callbacks<DocumentItemDetails> callbacks =
+                new KeyInputHandler.Callbacks<DocumentItemDetails>() {
             @Override
-            public boolean isInteractiveItem(ItemDetails item, KeyEvent e) {
+            public boolean isInteractiveItem(DocumentItemDetails item, KeyEvent e) {
                 switch (item.getItemViewType()) {
                     case DocumentsAdapter.ITEM_TYPE_HEADER_MESSAGE:
                     case DocumentsAdapter.ITEM_TYPE_INFLATED_MESSAGE:
@@ -95,7 +80,7 @@
             }
 
             @Override
-            public boolean onItemActivated(ItemDetails item, KeyEvent e) {
+            public boolean onItemActivated(DocumentItemDetails item, KeyEvent e) {
                 // Handle enter key events
                 switch (e.getKeyCode()) {
                     case KeyEvent.KEYCODE_ENTER:
@@ -116,7 +101,7 @@
             }
 
             @Override
-            public boolean onFocusItem(ItemDetails details, int keyCode, KeyEvent event) {
+            public boolean onFocusItem(DocumentItemDetails details, int keyCode, KeyEvent event) {
                 ViewHolder holder =
                         mRecView.findViewHolderForAdapterPosition(details.getPosition());
                 if (holder instanceof DocumentHolder) {
@@ -124,104 +109,8 @@
                 }
                 return false;
             }
-
-            @Override
-            public void onPerformHapticFeedback() {
-                mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-            }
         };
 
         return new KeyInputHandler(mSelectionHelper, mSelectionPredicate, callbacks);
     }
-
-    MouseInputHandler createMouseHandler(
-            EventHandler<MotionEvent> showContextMenuCallback) {
-
-        checkArgument(showContextMenuCallback != null);
-
-        MouseInputHandler.Callbacks callbacks = new MouseInputHandler.Callbacks() {
-            @Override
-            public boolean onItemActivated(ItemDetails item, MotionEvent e) {
-                return mActions.openItem(
-                        item,
-                        ActionHandler.VIEW_TYPE_REGULAR,
-                        ActionHandler.VIEW_TYPE_PREVIEW);
-            }
-
-            @Override
-            public boolean onContextClick(MotionEvent e) {
-                return showContextMenuCallback.accept(e);
-            }
-
-            @Override
-            public void onPerformHapticFeedback() {
-                mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-            }
-
-            @Override
-            public void focusItem(ItemDetails item) {
-                mFocusHandler.focusDocument(item.getStableId());
-            }
-
-            @Override
-            public void clearFocus() {
-                mFocusHandler.clearFocus();
-            }
-
-            @Override
-            public boolean hasFocusedItem() {
-                return mFocusHandler.hasFocusedItem();
-            }
-
-            @Override
-            public int getFocusedPosition() {
-                return mFocusHandler.getFocusPosition();
-            }
-        };
-
-        return new MouseInputHandler(mSelectionHelper, mDetailsLookup, callbacks);
-    }
-
-    /**
-     * Factory method for input touch delegate. Exists to reduce complexity in the
-     * calling scope.
-     * @param gestureHelper
-     */
-    TouchInputHandler createTouchHandler(
-            GestureSelectionHelper gestureHelper, DragStartListener dragStartListener) {
-        checkArgument(dragStartListener != null);
-
-        TouchInputHandler.Callbacks callbacks = new TouchInputHandler.Callbacks() {
-            @Override
-            public boolean onItemActivated(ItemDetails item, MotionEvent e) {
-                return mActions.openItem(
-                        item,
-                        ActionHandler.VIEW_TYPE_PREVIEW,
-                        ActionHandler.VIEW_TYPE_REGULAR);
-            }
-
-            @Override
-            public boolean onDragInitiated(MotionEvent e) {
-                return dragStartListener.onTouchDragEvent(e);
-            }
-
-            @Override
-            public void onPerformHapticFeedback() {
-                mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-            }
-
-            @Override
-            public void focusItem(ItemDetails item) {
-                mFocusHandler.focusDocument(item.getStableId());
-            }
-
-            @Override
-            public void clearFocus() {
-                mFocusHandler.clearFocus();
-            }
-        };
-
-        return new TouchInputHandler(
-                mSelectionHelper, mDetailsLookup, mSelectionPredicate, gestureHelper, callbacks);
-    }
 }
diff --git a/src/com/android/documentsui/dirlist/KeyInputHandler.java b/src/com/android/documentsui/dirlist/KeyInputHandler.java
index b70438a..826270e 100644
--- a/src/com/android/documentsui/dirlist/KeyInputHandler.java
+++ b/src/com/android/documentsui/dirlist/KeyInputHandler.java
@@ -17,31 +17,30 @@
 
 import android.view.KeyEvent;
 
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.SelectionTracker.SelectionPredicate;
+
 import com.android.documentsui.base.Events;
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.MotionInputHandler;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.documentsui.selection.MotionInputHandler.Callbacks;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
 
 import javax.annotation.Nullable;
 
+// TODO(b/69058726): Migrate to RecyclerView-Selection
 /**
  * Class that handles keyboard events on RecyclerView items. The input handler
  * must be attached directly to a RecyclerView item since, unlike DOM, events
  * don't appear bubble up.
  */
-public final class KeyInputHandler extends KeyboardEventListener {
+public final class KeyInputHandler extends KeyboardEventListener<DocumentItemDetails> {
 
-    private final SelectionHelper mSelectionHelper;
-    private final SelectionPredicate mSelectionPredicate;
-    private final Callbacks mCallbacks;
+    private final SelectionTracker<String> mSelectionHelper;
+    private final SelectionPredicate<String> mSelectionPredicate;
+    private final Callbacks<DocumentItemDetails> mCallbacks;
 
     public KeyInputHandler(
-            SelectionHelper selectionHelper,
-            SelectionPredicate selectionPredicate,
-            Callbacks callbacks) {
+            SelectionTracker<String> selectionHelper,
+            SelectionPredicate<String> selectionPredicate,
+            Callbacks<DocumentItemDetails> callbacks) {
 
         mSelectionHelper = selectionHelper;
         mSelectionPredicate = selectionPredicate;
@@ -49,7 +48,7 @@
     }
 
     @Override
-    public boolean onKey(@Nullable ItemDetails details, int keyCode, KeyEvent event) {
+    public boolean onKey(@Nullable DocumentItemDetails details, int keyCode, KeyEvent event) {
         // Only handle key-down events. This is simpler, consistent with most other UIs, and
         // enables the handling of repeated key events from holding down a key.
         if (event.getAction() != KeyEvent.ACTION_DOWN) {
@@ -96,19 +95,17 @@
         return mCallbacks.onItemActivated(details, event);
     }
 
-    private boolean shouldExtendSelection(ItemDetails item, KeyEvent event) {
+    private boolean shouldExtendSelection(DocumentItemDetails item, KeyEvent event) {
         if (!Events.isNavigationKeyCode(event.getKeyCode()) || !event.isShiftPressed()) {
             return false;
         }
 
-        return mSelectionPredicate.canSetStateForId(item.getStableId(), true);
+        return mSelectionPredicate.canSetStateForKey(item.getSelectionKey(), true);
     }
 
-    public static abstract class Callbacks extends MotionInputHandler.Callbacks {
-        public abstract boolean isInteractiveItem(ItemDetails item, KeyEvent e);
-        public abstract boolean onItemActivated(ItemDetails item, KeyEvent e);
-        public boolean onFocusItem(ItemDetails details, int keyCode, KeyEvent event) {
-            return true;
-        }
+    public static abstract class Callbacks<T extends ItemDetails<?>> {
+        public abstract boolean isInteractiveItem(T item, KeyEvent e);
+        public abstract boolean onItemActivated(T item, KeyEvent e);
+        public abstract boolean onFocusItem(T details, int keyCode, KeyEvent event);
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/documentsui/dirlist/KeyboardEventListener.java b/src/com/android/documentsui/dirlist/KeyboardEventListener.java
index fb1fc0a..d45885d 100644
--- a/src/com/android/documentsui/dirlist/KeyboardEventListener.java
+++ b/src/com/android/documentsui/dirlist/KeyboardEventListener.java
@@ -17,14 +17,13 @@
 
 import android.view.KeyEvent;
 
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
 
 /**
  * KeyboardListener is implemented by {@link KeyInputHandler}. The handler
  * must be called from RecyclerView.Holders in response to keyboard events.
  */
-public abstract class KeyboardEventListener {
+public abstract class KeyboardEventListener<T extends ItemDetails<?>> {
 
     /**
      * Handles key events on the view holder.
@@ -35,5 +34,5 @@
      *
      * @return Whether the event was handled.
      */
-    public abstract boolean onKey(ItemDetails details, int keyCode, KeyEvent event);
+    public abstract boolean onKey(T details, int keyCode, KeyEvent event);
 }
diff --git a/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/src/com/android/documentsui/dirlist/ListDocumentHolder.java
index f97410a..55b4ec0 100644
--- a/src/com/android/documentsui/dirlist/ListDocumentHolder.java
+++ b/src/com/android/documentsui/dirlist/ListDocumentHolder.java
@@ -18,7 +18,7 @@
 
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Rect;
@@ -34,7 +34,11 @@
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.Shared;
+import com.android.documentsui.base.State;
 import com.android.documentsui.roots.RootCursorWrapper;
+import com.android.documentsui.ui.Views;
+
+import java.util.function.Function;
 
 final class ListDocumentHolder extends DocumentHolder {
 
@@ -43,11 +47,11 @@
     private final TextView mDate;
     private final TextView mSize;
     private final TextView mType;
-    private final TextView mSummary;
     private final ImageView mIconMime;
     private final ImageView mIconThumb;
     private final ImageView mIconCheck;
     private final View mIconLayout;
+    final View mPreviewIcon;
 
     private final IconHelper mIconHelper;
     private final Lookup<String, String> mFileTypeLookup;
@@ -63,12 +67,12 @@
         mIconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb);
         mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check);
         mTitle = (TextView) itemView.findViewById(android.R.id.title);
-        mSummary = (TextView) itemView.findViewById(android.R.id.summary);
         mSize = (TextView) itemView.findViewById(R.id.size);
         mDate = (TextView) itemView.findViewById(R.id.date);
         mType = (TextView) itemView.findViewById(R.id.file_type);
         // Warning: mDetails view doesn't exists in layout-sw720dp-land layout
         mDetails = (LinearLayout) itemView.findViewById(R.id.line2);
+        mPreviewIcon = itemView.findViewById(R.id.preview_icon);
 
         mIconHelper = iconHelper;
         mFileTypeLookup = fileTypeLookup;
@@ -114,6 +118,21 @@
     }
 
     @Override
+    public void bindPreviewIcon(boolean show, Function<View, Boolean> clickCallback) {
+        if (mDoc.isDirectory()) {
+            mPreviewIcon.setVisibility(View.GONE);
+        } else {
+            mPreviewIcon.setVisibility(show ? View.VISIBLE : View.GONE);
+            if (show) {
+                mPreviewIcon.setContentDescription(
+                        itemView.getResources().getString(R.string.preview_file, mDoc.displayName));
+                mPreviewIcon.setAccessibilityDelegate(
+                        new PreviewAccessibilityDelegate(clickCallback));
+            }
+        }
+    }
+
+    @Override
     public boolean inDragRegion(MotionEvent event) {
         // If itemView is activated = selected, then whole region is interactive
         if (itemView.isActivated()) {
@@ -140,10 +159,13 @@
 
     @Override
     public boolean inSelectRegion(MotionEvent event) {
-        Rect iconRect = new Rect();
-        mIconLayout.getGlobalVisibleRect(iconRect);
+        return (mDoc.isDirectory() && !(mAction == State.ACTION_BROWSE)) ?
+                false : Views.isEventOver(event, mIconLayout);
+    }
 
-        return iconRect.contains((int) event.getRawX(), (int) event.getRawY());
+    @Override
+    public boolean inPreviewIconRegion(MotionEvent event) {
+        return Views.isEventOver(event, mPreviewIcon);
     }
 
     /**
@@ -177,20 +199,6 @@
             // Note, we don't show any details for any directory...ever.
             hasDetails = false;
         } else {
-            // Show summary if the file is partial. Otherwise, there tends
-            // to be a bunch of confusing junk in the summary field
-            // as populated by Downlaods (and others). So to make things
-            // simpler and clearer for the user in list view, we only
-            // show the summary if the file is partial >
-            // which we believe to mean actively downloading.
-            if (mDoc.isPartial() && mDoc.summary != null) {
-                hasDetails = true;
-                mSummary.setText(mDoc.summary);
-                mSummary.setVisibility(View.VISIBLE);
-            } else {
-                mSummary.setVisibility(View.INVISIBLE);
-            }
-
             if (mDoc.lastModified > 0) {
                 hasDetails = true;
                 mDate.setText(Shared.formatTime(mContext, mDoc.lastModified));
diff --git a/src/com/android/documentsui/dirlist/Message.java b/src/com/android/documentsui/dirlist/Message.java
index b81a72c..8478f68 100644
--- a/src/com/android/documentsui/dirlist/Message.java
+++ b/src/com/android/documentsui/dirlist/Message.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.dirlist;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.app.AuthenticationRequiredException;
 import android.app.PendingIntent;
 import android.graphics.drawable.Drawable;
diff --git a/src/com/android/documentsui/dirlist/MessageHolder.java b/src/com/android/documentsui/dirlist/MessageHolder.java
index 9268602..1d8d7d6 100644
--- a/src/com/android/documentsui/dirlist/MessageHolder.java
+++ b/src/com/android/documentsui/dirlist/MessageHolder.java
@@ -16,10 +16,7 @@
 
 package com.android.documentsui.dirlist;
 
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-
 import android.content.Context;
-import android.view.MotionEvent;
 import android.view.ViewGroup;
 import android.widget.Space;
 
@@ -36,7 +33,7 @@
     }
 
     @Override
-    public ItemDetails getItemDetails() {
+    public DocumentItemDetails getItemDetails() {
         return null;
     }
 }
diff --git a/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java b/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
index 99bb63c..da98ea6 100644
--- a/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
+++ b/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
@@ -23,16 +23,18 @@
 
 import android.database.Cursor;
 import android.provider.DocumentsContract.Document;
-import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 import android.view.ViewGroup;
 
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.documentsui.Model;
 import com.android.documentsui.Model.Update;
 import com.android.documentsui.base.EventListener;
 import com.android.documentsui.base.Lookup;
+import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
-import com.android.documentsui.selection.SelectionHelper;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -91,7 +93,9 @@
                         holder = new GridDirectoryHolder(mEnv.getContext(), parent);
                         break;
                     case ITEM_TYPE_DOCUMENT:
-                        holder = new GridDocumentHolder(mEnv.getContext(), parent, mIconHelper);
+                        holder = state.isPhotoPicking()
+                                ? new GridPhotoHolder(mEnv.getContext(), parent, mIconHelper)
+                                : new GridDocumentHolder(mEnv.getContext(), parent, mIconHelper);
                         break;
                     default:
                         throw new IllegalStateException("Unsupported layout type.");
@@ -111,7 +115,7 @@
 
     @Override
     public void onBindViewHolder(DocumentHolder holder, int position, List<Object> payload) {
-        if (payload.contains(SelectionHelper.SELECTION_CHANGED_MARKER)) {
+        if (payload.contains(SelectionTracker.SELECTION_CHANGED_MARKER)) {
             final boolean selected = mEnv.isSelected(mModelIds.get(position));
             holder.setSelected(selected, true);
         } else {
@@ -135,6 +139,10 @@
         }
         holder.setEnabled(enabled);
         holder.setSelected(mEnv.isSelected(modelId), false);
+        holder.setAction(mEnv.getDisplayState().action);
+        holder.bindPreviewIcon(Shared.hasQuickViewer(mEnv.getContext())
+                        && mEnv.getDisplayState().shouldShowPreview() && enabled,
+                view -> mEnv.getActionHandler().previewItem(holder.getItemDetails()));
 
         mEnv.onBindDocumentHolder(holder, cursor);
     }
diff --git a/src/com/android/documentsui/dirlist/MouseDragEventInterceptor.java b/src/com/android/documentsui/dirlist/MouseDragEventInterceptor.java
deleted file mode 100644
index fa40c26..0000000
--- a/src/com/android/documentsui/dirlist/MouseDragEventInterceptor.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.dirlist;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
-import android.view.MotionEvent;
-
-import com.android.documentsui.base.EventHandler;
-import com.android.documentsui.base.Events;
-import com.android.documentsui.selection.BandSelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.TouchEventRouter;
-
-/**
- * OnItemTouchListener that helps enable support for drag/drop functionality
- * in DirectoryFragment.
- *
- * <p>This class takes an OnItemTouchListener that is presumably the
- * one provided by {@link BandSelectionHelper#getListener()}, and
- * is used in conjunction with the {@link TouchEventRouter}.
- *
- * <p>See DirectoryFragment for more details on how this is glued
- * into DocumetnsUI event handling to make the magic happen.
- */
-class MouseDragEventInterceptor implements OnItemTouchListener {
-
-    private final ItemDetailsLookup mEventDetailsLookup;
-    private final EventHandler<MotionEvent> mMouseDragListener;
-    private final @Nullable OnItemTouchListener mDelegate;
-
-    public MouseDragEventInterceptor(
-            ItemDetailsLookup eventDetailsLookup,
-            EventHandler<MotionEvent> mouseDragListener,
-            @Nullable OnItemTouchListener delegate) {
-
-        checkArgument(eventDetailsLookup != null);
-        checkArgument(mouseDragListener != null);
-
-        mEventDetailsLookup = eventDetailsLookup;
-        mMouseDragListener = mouseDragListener;
-        mDelegate = delegate;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
-        if (Events.isMouseDragEvent(e) && mEventDetailsLookup.inItemDragRegion(e)) {
-            return mMouseDragListener.accept(e);
-        } else if (mDelegate != null) {
-            return mDelegate.onInterceptTouchEvent(rv, e);
-        }
-        return false;
-    }
-
-    @Override
-    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
-        if (mDelegate != null) {
-            mDelegate.onTouchEvent(rv, e);
-        }
-    }
-
-    @Override
-    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
-}
diff --git a/src/com/android/documentsui/dirlist/RefreshHelper.java b/src/com/android/documentsui/dirlist/RefreshHelper.java
index a1a5662..fb7b478 100644
--- a/src/com/android/documentsui/dirlist/RefreshHelper.java
+++ b/src/com/android/documentsui/dirlist/RefreshHelper.java
@@ -15,10 +15,10 @@
  */
 package com.android.documentsui.dirlist;
 
-import static android.support.v4.util.Preconditions.checkState;
+import static androidx.core.util.Preconditions.checkState;
 
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
 import android.view.MotionEvent;
 
 import com.android.documentsui.base.BooleanConsumer;
diff --git a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
index 2573448..d78f10a 100644
--- a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
+++ b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -18,22 +18,11 @@
 
 import static com.android.documentsui.base.SharedMinimal.TAG;
 
-import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
-import android.support.design.widget.Snackbar;
-import android.support.design.widget.TextInputLayout;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -44,14 +33,22 @@
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;
+
 import com.android.documentsui.BaseActivity;
-import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.ui.Snackbars;
 
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputLayout;
+
 /**
  * Dialog to rename file or directory.
  */
@@ -76,12 +73,13 @@
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         Context context = getActivity();
-        AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
         LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
         View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false);
 
         mEditText = (EditText) view.findViewById(android.R.id.text1);
-        mRenameInputWrapper = (TextInputLayout) view.findViewById(R.id.rename_input_wrapper);
+        mRenameInputWrapper = (TextInputLayout) view.findViewById(R.id.input_wrapper);
+        mRenameInputWrapper.setHint(getString(R.string.input_hint_rename));
         builder.setTitle(R.string.menu_rename);
         builder.setView(view);
         builder.setPositiveButton(android.R.string.ok, null);
@@ -198,7 +196,7 @@
         } else if (activity.getInjector().getModel().hasFileWithName(newDisplayName)){
             mRenameInputWrapper.setError(getContext().getString(R.string.name_conflict));
             selectFileName(mEditText);
-            Metrics.logRenameFileError(getContext());
+            Metrics.logRenameFileError();
         } else {
             new RenameDocumentsTask(activity, newDisplayName).execute(mDocument);
         }
@@ -229,10 +227,10 @@
         @Override
         protected void onPostExecute(DocumentInfo result) {
             if (result != null) {
-                Metrics.logRenameFileOperation(getContext());
+                Metrics.logRenameFileOperation();
             } else {
                 Snackbars.showRenameFailed(mActivity);
-                Metrics.logRenameFileError(getContext());
+                Metrics.logRenameFileError();
             }
             if (mDialog != null) {
                 mDialog.dismiss();
diff --git a/src/com/android/documentsui/dirlist/ScaleHelper.java b/src/com/android/documentsui/dirlist/ScaleHelper.java
index 84b939d..3f048f5 100644
--- a/src/com/android/documentsui/dirlist/ScaleHelper.java
+++ b/src/com/android/documentsui/dirlist/ScaleHelper.java
@@ -15,14 +15,15 @@
  */
 package com.android.documentsui.dirlist;
 
-import static android.support.v4.util.Preconditions.checkState;
+import static androidx.core.util.Preconditions.checkState;
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
 import android.content.Context;
 import android.os.Build;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
@@ -61,7 +62,7 @@
     }
 
     void attach(RecyclerView view) {
-        checkState(Build.IS_DEBUGGABLE);
+        checkState(DEBUG);
         checkState(mScaleDetector == null);
 
         mScaleDetector = new ScaleGestureDetector(
diff --git a/src/com/android/documentsui/dirlist/SelectionMetadata.java b/src/com/android/documentsui/dirlist/SelectionMetadata.java
index 3ac3a07..3abc3e1 100644
--- a/src/com/android/documentsui/dirlist/SelectionMetadata.java
+++ b/src/com/android/documentsui/dirlist/SelectionMetadata.java
@@ -23,11 +23,12 @@
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
+import androidx.recyclerview.selection.SelectionTracker.SelectionObserver;
+
 import com.android.documentsui.MenuManager;
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.base.MimeTypes;
 import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
 
 import java.util.function.Function;
 
@@ -38,7 +39,7 @@
  * <p>By collecting information in real-time as the selection changes the need to
  * traverse the entire selection in order to answer questions is eliminated.
  */
-public class SelectionMetadata extends SelectionObserver
+public class SelectionMetadata extends SelectionObserver<String>
         implements MenuManager.SelectionDetails {
 
     private static final String TAG = "SelectionMetadata";
@@ -107,7 +108,7 @@
     }
 
     @Override
-    public void onSelectionReset() {
+    public void onSelectionRefresh() {
         mFileCount = 0;
         mDirectoryCount = 0;
         mPartialCount = 0;
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 6b5a0a2..4d4f082 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -16,21 +16,29 @@
 
 package com.android.documentsui.files;
 
+import static android.content.ContentResolver.wrap;
+
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.app.Activity;
+import android.app.DownloadManager;
 import android.content.ActivityNotFoundException;
 import android.content.ClipData;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.net.Uri;
-import android.os.Build;
+import android.os.FileUtils;
 import android.provider.DocumentsContract;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.DragEvent;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.FragmentActivity;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.Selection;
+
 import com.android.documentsui.AbstractActionHandler;
 import com.android.documentsui.ActionModeAddons;
 import com.android.documentsui.ActivityConfig;
@@ -38,12 +46,12 @@
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.DragAndDropManager;
 import com.android.documentsui.Injector;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.Model;
 import com.android.documentsui.R;
 import com.android.documentsui.TimeoutTask;
 import com.android.documentsui.base.ConfirmationCallback;
-import com.android.documentsui.base.ConfirmationCallback.Result;
 import com.android.documentsui.base.DebugFlags;
 import com.android.documentsui.base.DocumentFilters;
 import com.android.documentsui.base.DocumentInfo;
@@ -51,6 +59,7 @@
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.MimeTypes;
+import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
@@ -62,14 +71,10 @@
 import com.android.documentsui.inspector.InspectorActivity;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.ProvidersAccess;
-import com.android.documentsui.selection.MutableSelection;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperations;
 import com.android.documentsui.ui.DialogController;
-import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -80,7 +85,7 @@
 /**
  * Provides {@link FilesActivity} action specializations to fragments.
  */
-public class ActionHandler<T extends Activity & Addons> extends AbstractActionHandler<T> {
+public class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionHandler<T> {
 
     private static final String TAG = "ManagerActionHandler";
 
@@ -136,7 +141,7 @@
 
     @Override
     public void openSelectedInNewWindow() {
-        Selection selection = getStableSelection();
+        Selection<String> selection = getStableSelection();
         assert(selection.size() == 1);
         DocumentInfo doc = mModel.getDocument(selection.iterator().next());
         assert(doc != null);
@@ -145,7 +150,7 @@
 
     @Override
     public void openSettings(RootInfo root) {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_SETTINGS);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_SETTINGS);
         final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
         intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
         mActivity.startActivity(intent);
@@ -173,31 +178,32 @@
             client = DocumentsApplication.acquireUnstableProviderOrThrow(
                     resolver, document.derivedUri.getAuthority());
             Uri newUri = DocumentsContract.renameDocument(
-                    client, document.derivedUri, name);
+                    wrap(client), document.derivedUri, name);
             return DocumentInfo.fromUri(resolver, newUri);
         } catch (Exception e) {
             Log.w(TAG, "Failed to rename file", e);
             return null;
         } finally {
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(client);
         }
     }
 
     @Override
     public void openRoot(RootInfo root) {
-        Metrics.logRootVisited(mActivity, Metrics.FILES_SCOPE, root);
+        Metrics.logRootVisited(MetricConsts.FILES_SCOPE, root);
         mActivity.onRootPicked(root);
     }
 
     @Override
-    public boolean openItem(ItemDetails details, @ViewType int type,
+    public boolean openItem(ItemDetails<String> details, @ViewType int type,
             @ViewType int fallback) {
-        DocumentInfo doc = mModel.getDocument(details.getStableId());
+        DocumentInfo doc = mModel.getDocument(details.getSelectionKey());
         if (doc == null) {
-            Log.w(TAG,
-                    "Can't view item. No Document available for modeId: " + details.getStableId());
+            Log.w(TAG, "Can't view item. No Document available for modeId: "
+                    + details.getSelectionKey());
             return false;
         }
+        mInjector.searchManager.recordHistory();
 
         return openDocument(doc, type, fallback);
     }
@@ -208,7 +214,7 @@
         if (mConfig.isDocumentEnabled(doc.mimeType, doc.flags, mState)) {
             onDocumentPicked(doc, type, fallback);
             mSelectionMgr.clearSelection();
-            return true;
+            return !doc.isContainer();
         }
         return false;
     }
@@ -220,8 +226,8 @@
         openContainerDocument(doc);
     }
 
-    private Selection getSelectedOrFocused() {
-        final MutableSelection selection = this.getStableSelection();
+    private Selection<String> getSelectedOrFocused() {
+        final MutableSelection<String> selection = this.getStableSelection();
         if (selection.isEmpty()) {
             String focusModelId = mFocusHandler.getFocusModelId();
             if (focusModelId != null) {
@@ -234,8 +240,8 @@
 
     @Override
     public void cutToClipboard() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_CUT_CLIPBOARD);
-        Selection selection = getSelectedOrFocused();
+        Metrics.logUserAction(MetricConsts.USER_ACTION_CUT_CLIPBOARD);
+        Selection<String> selection = getSelectedOrFocused();
 
         if (selection.isEmpty()) {
             return;
@@ -255,8 +261,8 @@
 
     @Override
     public void copyToClipboard() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_COPY_CLIPBOARD);
-        Selection selection = getSelectedOrFocused();
+        Metrics.logUserAction(MetricConsts.USER_ACTION_COPY_CLIPBOARD);
+        Selection<String> selection = getSelectedOrFocused();
 
         if (selection.isEmpty()) {
             return;
@@ -270,8 +276,8 @@
 
     @Override
     public void viewInOwner() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_VIEW_IN_APPLICATION);
-        Selection selection = getSelectedOrFocused();
+        Metrics.logUserAction(MetricConsts.USER_ACTION_VIEW_IN_APPLICATION);
+        Selection<String> selection = getSelectedOrFocused();
 
         if (selection.isEmpty() || selection.size() > 1) {
             return;
@@ -292,7 +298,7 @@
 
     @Override
     public void deleteSelectedDocuments() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_DELETE);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_DELETE);
         Selection selection = getSelectedOrFocused();
 
         if (selection.isEmpty()) {
@@ -304,7 +310,7 @@
         // Model must be accessed in UI thread, since underlying cursor is not threadsafe.
         List<DocumentInfo> docs = mModel.getDocuments(selection);
 
-        ConfirmationCallback result = (@Result int code) -> {
+        ConfirmationCallback result = (@ConfirmationCallback.Result int code) -> {
             // share the news with our caller, be it good or bad.
             mActionModeAddons.finishOnConfirmed(code);
 
@@ -343,9 +349,9 @@
 
     @Override
     public void shareSelectedDocuments() {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_SHARE);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_SHARE);
 
-        Selection selection = getStableSelection();
+        Selection<String> selection = getStableSelection();
 
         assert(!selection.isEmpty());
 
@@ -394,39 +400,65 @@
     }
 
     @Override
+    public void loadDocumentsForCurrentStack() {
+        super.loadDocumentsForCurrentStack();
+    }
+
+    @Override
     public void initLocation(Intent intent) {
         assert(intent != null);
 
         // stack is initialized if it's restored from bundle, which means we're restoring a
         // previously stored state.
         if (mState.stack.isInitialized()) {
-            if (DEBUG) Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
+            if (DEBUG) {
+                Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
+            }
             restoreRootAndDirectory();
             return;
         }
 
         if (launchToStackLocation(intent)) {
-            if (DEBUG) Log.d(TAG, "Launched to location from stack.");
+            if (DEBUG) {
+                Log.d(TAG, "Launched to location from stack.");
+            }
             return;
         }
 
         if (launchToRoot(intent)) {
-            if (DEBUG) Log.d(TAG, "Launched to root for browsing.");
+            if (DEBUG) {
+                Log.d(TAG, "Launched to root for browsing.");
+            }
             return;
         }
 
         if (launchToDocument(intent)) {
-            if (DEBUG) Log.d(TAG, "Launched to a document.");
+            if (DEBUG) {
+                Log.d(TAG, "Launched to a document.");
+            }
             return;
         }
 
-        if (DEBUG) Log.d(TAG, "Launching directly into Home directory.");
-        loadHomeDir();
+        if (launchToDownloads(intent)) {
+            if (DEBUG) {
+                Log.d(TAG, "Launched to a downloads.");
+            }
+            return;
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Launching directly into Home directory.");
+        }
+        launchToDefaultLocation();
     }
 
     @Override
     protected void launchToDefaultLocation() {
-        loadHomeDir();
+        if (mFeatures.isDefaultRootInBrowseEnabled()) {
+            loadHomeDir();
+        } else {
+            loadRecent();
+        }
     }
 
     // If EXTRA_STACK is not null in intent, we'll skip other means of loading
@@ -460,11 +492,21 @@
         if (Intent.ACTION_VIEW.equals(action)) {
             Uri uri = intent.getData();
             if (DocumentsContract.isRootUri(mActivity, uri)) {
-                if (DEBUG) Log.d(TAG, "Launching with root URI.");
+                if (DEBUG) {
+                    Log.d(TAG, "Launching with root URI.");
+                }
                 // If we've got a specific root to display, restore that root using a dedicated
                 // authority. That way a misbehaving provider won't result in an ANR.
                 loadRoot(uri);
                 return true;
+            } else if (DocumentsContract.isRootsUri(mActivity, uri)) {
+                if (DEBUG) {
+                    Log.d(TAG, "Launching first root with roots URI.");
+                }
+                // TODO: b/116760996 Let the user can disambiguate between roots if there are
+                // multiple from DocumentsProvider instead of launching the first root in default
+                loadFirstRoot(uri);
+                return true;
             }
         }
         return false;
@@ -481,6 +523,17 @@
         return false;
     }
 
+    private boolean launchToDownloads(Intent intent) {
+        if (DownloadManager.ACTION_VIEW_DOWNLOADS.equals(intent.getAction())) {
+            Uri uri = DocumentsContract.buildRootUri(Providers.AUTHORITY_DOWNLOADS,
+                    Providers.ROOT_ID_DOWNLOADS);
+            loadRoot(uri);
+            return true;
+        }
+
+        return false;
+    }
+
     @Override
     public void showChooserForDoc(DocumentInfo doc) {
         assert(!doc.isDirectory());
@@ -491,9 +544,7 @@
         }
 
         Intent intent = Intent.createChooser(buildViewIntent(doc), null);
-        if (Features.OMC_RUNTIME) {
-            intent.putExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, false);
-        }
+        intent.putExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, false);
         try {
             mActivity.startActivity(intent);
         } catch (ActivityNotFoundException e) {
@@ -602,7 +653,8 @@
                 mActivity.getPackageManager(),
                 mActivity.getResources(),
                 doc,
-                mModel).build();
+                mModel,
+                false /* fromPicker */).build();
 
         if (intent != null) {
             // TODO: un-work around issue b/24963914. Should be fixed soon.
@@ -687,7 +739,7 @@
 
     @Override
     public void showInspector(DocumentInfo doc) {
-        Metrics.logUserAction(mActivity, Metrics.USER_ACTION_INSPECTOR);
+        Metrics.logUserAction(MetricConsts.USER_ACTION_INSPECTOR);
         Intent intent = new Intent(mActivity, InspectorActivity.class);
         intent.setData(doc.derivedUri);
 
@@ -695,7 +747,7 @@
         intent.putExtra(
                 Shared.EXTRA_SHOW_DEBUG,
                 mFeatures.isDebugSupportEnabled() &&
-                        (Build.IS_DEBUGGABLE || DebugFlags.getDocumentDetailsEnabled()));
+                        (DEBUG || DebugFlags.getDocumentDetailsEnabled()));
 
         // The "root document" (top level folder in a root) don't usually have a
         // human friendly display name. That's because we've never shown the root
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index f17e175..d93e5db 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -19,22 +19,18 @@
 import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
 
 import android.app.ActivityManager.TaskDescription;
-import android.app.FragmentManager;
 import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
-import android.support.annotation.CallSuper;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.View;
+
+import androidx.annotation.CallSuper;
+import androidx.fragment.app.FragmentManager;
 
 import com.android.documentsui.ActionModeController;
 import com.android.documentsui.BaseActivity;
@@ -55,6 +51,7 @@
 import com.android.documentsui.base.State;
 import com.android.documentsui.clipping.DocumentClipper;
 import com.android.documentsui.dirlist.AnimationView.AnimationType;
+import com.android.documentsui.dirlist.AppsRowManager;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.prefs.ScopedPreferences;
 import com.android.documentsui.services.FileOperationService;
@@ -104,14 +101,14 @@
         super.onCreate(icicle);
 
         DocumentClipper clipper = DocumentsApplication.getDocumentClipper(this);
-        mInjector.selectionMgr = DocsSelectionHelper.createMultiSelect();
+        mInjector.selectionMgr = DocsSelectionHelper.create();
 
         mInjector.focusManager = new FocusManager(
                 mInjector.features,
                 mInjector.selectionMgr,
                 mDrawer,
                 this::focusSidebar,
-                getColor(R.color.accent_dark));
+                getColor(R.color.primary));
 
         mInjector.menuManager = new MenuManager(
                 mInjector.features,
@@ -149,6 +146,9 @@
 
         mInjector.searchManager = mSearchManager;
 
+        mAppsRowManager = new AppsRowManager(mInjector.actions);
+        mInjector.appsRowManager = mAppsRowManager;
+
         mActivityInputHandler =
                 new ActivityInputHandler(mInjector.actions::deleteSelectedDocuments);
         mSharedInputHandler =
@@ -157,9 +157,10 @@
                         mInjector.selectionMgr,
                         mInjector.searchManager::cancelSearch,
                         this::popDir,
-                        mInjector.features);
+                        mInjector.features,
+                        mDrawer);
 
-        RootsFragment.show(getFragmentManager(), null);
+        RootsFragment.show(getSupportFragmentManager(), null);
 
         final Intent intent = getIntent();
 
@@ -172,6 +173,10 @@
             updateTaskDescription(intent);
         }
 
+        // Set save container background to transparent for edge to edge nav bar.
+        View saveContainer = findViewById(R.id.container_save);
+        saveContainer.setBackgroundColor(Color.TRANSPARENT);
+
         presentFileErrors(icicle, intent);
     }
 
@@ -194,60 +199,7 @@
         int iconRes = intent.getIntExtra(LauncherActivity.TASK_ICON_RES, -1);
         assert(iconRes > -1);
 
-        Drawable drawable = getResources().getDrawable(
-                iconRes,
-                null  // we don't care about theme, since the supplier should have handled that.
-                );
-
-        setTaskDescription(new TaskDescription(label, flattenDrawableToBitmap(drawable)));
-    }
-
-    // AdaptiveIconDrawable assumes that the consumer of the icon applies the shadow and
-    // recents assume that the provider of the task description handles these. Hence,
-    // we apply the shadow treatment same as Launcher3 implementation.
-    private Bitmap flattenDrawableToBitmap(Drawable d) {
-        // Percent of actual icon size
-        float ICON_SIZE_BLUR_FACTOR = 0.5f/48;
-        // Percent of actual icon size
-        float ICON_SIZE_KEY_SHADOW_DELTA_FACTOR = 1f/48;
-        int KEY_SHADOW_ALPHA = 61;
-        int AMBIENT_SHADOW_ALPHA = 30;
-        if (d instanceof BitmapDrawable) {
-            return ((BitmapDrawable) d).getBitmap();
-        } else if (d instanceof AdaptiveIconDrawable) {
-            AdaptiveIconDrawable aid = (AdaptiveIconDrawable) d;
-            int iconSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
-            int shadowSize = Math.max(iconSize, aid.getIntrinsicHeight());
-            aid.setBounds(0, 0, shadowSize, shadowSize);
-
-            float blur = ICON_SIZE_BLUR_FACTOR * shadowSize;
-            float keyShadowDistance = ICON_SIZE_KEY_SHADOW_DELTA_FACTOR * shadowSize;
-
-            int bitmapSize = (int) (shadowSize + 2 * blur + keyShadowDistance);
-            Bitmap shadow = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
-
-            Canvas canvas = new Canvas(shadow);
-            canvas.translate(blur + keyShadowDistance / 2, blur);
-
-            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            paint.setColor(Color.TRANSPARENT);
-
-            // Draw ambient shadow
-            paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
-            canvas.drawPath(aid.getIconMask(), paint);
-
-            // Draw key shadow
-            canvas.translate(0, keyShadowDistance);
-            paint.setShadowLayer(blur, 0, 0, KEY_SHADOW_ALPHA << 24);
-            canvas.drawPath(aid.getIconMask(), paint);
-
-            // Draw original drawable
-            aid.draw(canvas);
-
-            canvas.setBitmap(null);
-            return shadow;
-        }
-        return null;
+        setTaskDescription(new TaskDescription(label, iconRes));
     }
 
     private void presentFileErrors(Bundle icicle, final Intent intent) {
@@ -264,7 +216,7 @@
             final ArrayList<Uri> uriList =
                     intent.getParcelableArrayListExtra(FileOperationService.EXTRA_FAILED_URIS);
             OperationDialogFragment.show(
-                    getFragmentManager(),
+                    getSupportFragmentManager(),
                     dialogType,
                     docList,
                     uriList,
@@ -368,7 +320,7 @@
 
     @Override
     public void refreshDirectory(@AnimationType int anim) {
-        final FragmentManager fm = getFragmentManager();
+        final FragmentManager fm = getSupportFragmentManager();
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
 
diff --git a/src/com/android/documentsui/files/LauncherActivity.java b/src/com/android/documentsui/files/LauncherActivity.java
index f14be5a..8cd7dcb 100644
--- a/src/com/android/documentsui/files/LauncherActivity.java
+++ b/src/com/android/documentsui/files/LauncherActivity.java
@@ -26,7 +26,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.util.Log;
 
 import com.android.documentsui.R;
@@ -103,12 +103,16 @@
 
         // Forward any flags from the original intent.
         intent.setFlags(getIntent().getFlags());
-        if (DEBUG) Log.d(TAG, "Starting new task > " + intent.getData());
+        if (DEBUG) {
+            Log.d(TAG, "Starting new task > " + intent.getData());
+        }
         startActivity(intent);
     }
 
     private boolean restoreTask(Intent intent) {
-        if (DEBUG) Log.d(TAG, "Restoring existing task > " + intent.getData());
+        if (DEBUG) {
+            Log.d(TAG, "Restoring existing task > " + intent.getData());
+        }
         try {
             // TODO: This doesn't appear to restore a task once it has stopped running.
             startActivity(intent);
diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java
index e2f39d5..ab7c630 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -16,7 +16,6 @@
 
 package com.android.documentsui.files;
 
-import android.app.Fragment;
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.Uri;
@@ -28,15 +27,16 @@
 import android.view.MenuItem;
 import android.view.View;
 
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.selection.SelectionTracker;
+
 import com.android.documentsui.R;
-import com.android.documentsui.MenuManager.SelectionDetails;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.queries.SearchViewManager;
-import com.android.documentsui.selection.SelectionHelper;
 
 import java.util.List;
 import java.util.function.IntFunction;
@@ -45,7 +45,7 @@
 
     private final Features mFeatures;
     private final Context mContext;
-    private final SelectionHelper mSelectionManager;
+    private final SelectionTracker<String> mSelectionManager;
     private final Lookup<String, Uri> mUriLookup;
     private final Lookup<String, String> mAppNameLookup;
 
@@ -55,7 +55,7 @@
             State displayState,
             DirectoryDetails dirDetails,
             Context context,
-            SelectionHelper selectionManager,
+            SelectionTracker<String> selectionManager,
             Lookup<String, String> appNameLookup,
             Lookup<String, Uri> uriLookup) {
 
@@ -69,14 +69,6 @@
     }
 
     @Override
-    public void updateOptionMenu(Menu menu) {
-        super.updateOptionMenu(menu);
-
-        // It hides icon if searching in progress
-        mSearchManager.updateMenu();
-    }
-
-    @Override
     public void updateKeyboardShortcutsMenu(
             List<KeyboardShortcutGroup> data, IntFunction<String> stringSupplier) {
         KeyboardShortcutGroup group = new KeyboardShortcutGroup(
@@ -164,13 +156,6 @@
     }
 
     @Override
-    protected void updateOpenInContextMenu(MenuItem open, SelectionDetails selectionDetails) {
-        open.setVisible(true);
-        open.setEnabled(selectionDetails.size() == 1
-                && !selectionDetails.containsPartialFiles());
-    }
-
-    @Override
     protected void updateOpenWith(MenuItem openWith, SelectionDetails selectionDetails) {
         openWith.setVisible(true);
         openWith.setEnabled(selectionDetails.canOpenWith());
@@ -282,7 +267,8 @@
 
     @Override
     protected void updateViewInOwner(MenuItem view, SelectionDetails selectionDetails) {
-        if (selectionDetails.canViewInOwner()) {
+        if (selectionDetails.canViewInOwner() &&
+                mSelectionManager.getSelection().iterator().hasNext()) {
             view.setVisible(true);
             view.setEnabled(true);
             Resources res = mContext.getResources();
diff --git a/src/com/android/documentsui/files/QuickViewIntentBuilder.java b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
index 0226146..236a36c 100644
--- a/src/com/android/documentsui/files/QuickViewIntentBuilder.java
+++ b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
@@ -31,7 +31,7 @@
 import android.os.Build;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Range;
@@ -67,6 +67,9 @@
             QuickViewConstants.FEATURE_DOWNLOAD,
             QuickViewConstants.FEATURE_PRINT
     };
+    private static final String[] PICKER_FEATURES = {
+            QuickViewConstants.FEATURE_VIEW
+    };
 
     private final DocumentInfo mDocument;
     private final Model mModel;
@@ -74,11 +77,14 @@
     private final PackageManager mPackageMgr;
     private final Resources mResources;
 
+    private final boolean mFromPicker;
+
     public QuickViewIntentBuilder(
             PackageManager packageMgr,
             Resources resources,
             DocumentInfo doc,
-            Model model) {
+            Model model,
+            boolean fromPicker) {
 
         assert(packageMgr != null);
         assert(resources != null);
@@ -89,14 +95,17 @@
         mResources = resources;
         mDocument = doc;
         mModel = model;
+        mFromPicker = fromPicker;
     }
 
     /**
      * Builds the intent for quick viewing. Short circuits building if a handler cannot
      * be resolved; in this case {@code null} is returned.
      */
-    @Nullable Intent build() {
-        if (DEBUG) Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);
+    @Nullable public Intent build() {
+        if (DEBUG) {
+            Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);
+        }
 
         String trustedPkg = getQuickViewPackage();
 
@@ -107,7 +116,7 @@
                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
             intent.setPackage(trustedPkg);
             if (hasRegisteredHandler(intent)) {
-                includeQuickViewFeaturesFlag(intent, mDocument);
+                includeQuickViewFeaturesFlag(intent, mDocument, mFromPicker);
 
                 final ArrayList<Uri> uris = new ArrayList<>();
                 final int documentLocation = collectViewableUris(uris);
@@ -119,7 +128,9 @@
                 for (int i = range.getLower(); i <= range.getUpper(); i++) {
                     uri = uris.get(i);
                     item = new ClipData.Item(uri);
-                    if (DEBUG) Log.d(TAG, "Including file: " + uri);
+                    if (DEBUG) {
+                        Log.d(TAG, "Including file: " + uri);
+                    }
                     if (clipData == null) {
                         clipData = new ClipData(
                                 "URIs", new String[] { ClipDescription.MIMETYPE_TEXT_URILIST },
@@ -154,12 +165,11 @@
 
         // Allow users of debug devices to override default quick viewer
         // for the purposes of testing.
-        if (Build.IS_DEBUGGABLE) {
+        if (DEBUG) {
             String quickViewer = DebugFlags.getQuickViewer();
             if (quickViewer != null) {
                 return quickViewer;
             }
-            return android.os.SystemProperties.get("debug.quick_viewer", resValue);
         }
         return resValue;
     }
@@ -180,17 +190,21 @@
             cursor = mModel.getItem(siblingIds[i]);
 
             if (cursor == null) {
-                if (DEBUG) Log.d(TAG,
+                if (DEBUG) {
+                    Log.d(TAG,
                         "Unable to obtain cursor for sibling document, modelId: "
-                        + siblingIds[i]);
+                            + siblingIds[i]);
+                }
                 continue;
             }
 
             mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
             if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-                if (DEBUG) Log.d(TAG,
+                if (DEBUG) {
+                    Log.d(TAG,
                         "Skipping directory, not supported by quick view. modelId: "
-                        + siblingIds[i]);
+                            + siblingIds[i]);
+                }
                 continue;
             }
 
@@ -202,7 +216,9 @@
 
             if (id.equals(mDocument.documentId)) {
                 documentLocation = uris.size() - 1;  // Position in "uris", not in the model.
-                if (DEBUG) Log.d(TAG, "Found starting point for QV. " + documentLocation);
+                if (DEBUG) {
+                    Log.d(TAG, "Found starting point for QV. " + documentLocation);
+                }
             }
         }
 
@@ -214,10 +230,12 @@
         return intent.resolveActivity(mPackageMgr) != null;
     }
 
-    private static void includeQuickViewFeaturesFlag(Intent intent, DocumentInfo doc) {
+    private static void includeQuickViewFeaturesFlag(Intent intent, DocumentInfo doc,
+            boolean fromPicker) {
         intent.putExtra(
                 Intent.EXTRA_QUICK_VIEW_FEATURES,
-                doc.isInArchive() ? IN_ARCHIVE_FEATURES : FULL_FEATURES);
+                doc.isInArchive() ? IN_ARCHIVE_FEATURES
+                        : fromPicker ? PICKER_FEATURES : FULL_FEATURES);
     }
 
     private static Range<Integer> computeSiblingsRange(List<Uri> uris, int documentLocation) {
@@ -234,8 +252,10 @@
             firstSibling = Math.max(0, lastSibling - MAX_DOCS_IN_INTENT + 1);
         }
 
-        if (DEBUG) Log.d(TAG, "Copmuted siblings from index: " + firstSibling
+        if (DEBUG) {
+            Log.d(TAG, "Copmuted siblings from index: " + firstSibling
                 + " to: " + lastSibling);
+        }
 
         return new Range(firstSibling, lastSibling);
     }
diff --git a/src/com/android/documentsui/inspector/DebugView.java b/src/com/android/documentsui/inspector/DebugView.java
index 03427e5..1dc2da7 100644
--- a/src/com/android/documentsui/inspector/DebugView.java
+++ b/src/com/android/documentsui/inspector/DebugView.java
@@ -15,7 +15,6 @@
  */
 package com.android.documentsui.inspector;
 
-import android.annotation.StringRes;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncTask;
@@ -24,6 +23,8 @@
 import android.util.AttributeSet;
 import android.widget.TextView;
 
+import androidx.annotation.StringRes;
+
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DummyLookup;
@@ -64,13 +65,12 @@
 
     void init(Lookup<String, Executor> executors) {
         assert executors != null;
-        setBackgroundColor(0xFFFFFFFF);  // it's just debug. We do what we want!
         mExecutors = executors;
     }
 
     @Override
     public void accept(DocumentInfo info) {
-        setTitle(R.string.inspector_debug_section, false);
+        setTitle(R.string.inspector_debug_section, true);
 
         put(R.string.debug_content_uri, info.derivedUri.toString());
         put(R.string.debug_document_id, info.documentId);
@@ -84,6 +84,7 @@
         put(R.string.debug_supports_create, info.isCreateSupported());
         put(R.string.debug_supports_delete, info.isDeleteSupported());
         put(R.string.debug_supports_metadata, info.isMetadataSupported());
+        put(R.string.debug_supports_move, info.isMoveSupported());
         put(R.string.debug_supports_remove, info.isRemoveSupported());
         put(R.string.debug_supports_rename, info.isRenameSupported());
         put(R.string.debug_supports_settings, info.isSettingsSupported());
diff --git a/src/com/android/documentsui/inspector/DetailsView.java b/src/com/android/documentsui/inspector/DetailsView.java
index 5563471..8b30097 100644
--- a/src/com/android/documentsui/inspector/DetailsView.java
+++ b/src/com/android/documentsui/inspector/DetailsView.java
@@ -43,7 +43,9 @@
     }
 
     @Override
-    public void accept(DocumentInfo doc) {
+    public void accept(DocumentInfo doc, String displayName) {
+
+        putTitle(displayName, false);
 
         Lookup<String, String> fileTypeLookup =
                 DocumentsApplication.getFileTypeLookup(getContext());
diff --git a/src/com/android/documentsui/inspector/HeaderTextSelector.java b/src/com/android/documentsui/inspector/HeaderTextSelector.java
index 5530fbe..9593844 100644
--- a/src/com/android/documentsui/inspector/HeaderTextSelector.java
+++ b/src/com/android/documentsui/inspector/HeaderTextSelector.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.inspector;
 
-import static com.android.internal.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 
 import android.text.Spannable;
 import android.view.ActionMode;
diff --git a/src/com/android/documentsui/inspector/HeaderView.java b/src/com/android/documentsui/inspector/HeaderView.java
index c411082..3aa1f22 100644
--- a/src/com/android/documentsui/inspector/HeaderView.java
+++ b/src/com/android/documentsui/inspector/HeaderView.java
@@ -20,16 +20,14 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.drawable.Drawable;
-import android.text.Selection;
-import android.text.Spannable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
 import android.widget.RelativeLayout;
-import android.widget.TextView;
 
+import com.android.documentsui.IconUtils;
 import com.android.documentsui.ProviderExecutor;
 import com.android.documentsui.R;
 import com.android.documentsui.ThumbnailLoader;
@@ -49,7 +47,6 @@
     private final Context mContext;
     private final View mHeader;
     private ImageView mThumbnail;
-    private final TextView mTitle;
     private Point mImageDimensions;
 
     public HeaderView(Context context) {
@@ -67,7 +64,6 @@
         mContext = context;
         mHeader = inflater.inflate(R.layout.inspector_header, null);
         mThumbnail = (ImageView) mHeader.findViewById(R.id.inspector_thumbnail);
-        mTitle = (TextView) mHeader.findViewById(R.id.inspector_file_title);
 
         int width = (int) Display.screenWidth((Activity)context);
         int height = mContext.getResources().getDimensionPixelSize(R.dimen.inspector_header_height);
@@ -76,15 +72,8 @@
     }
 
     @Override
-    public void accept(DocumentInfo info, String displayName) {
+    public void accept(DocumentInfo info) {
         loadHeaderImage(info);
-        mTitle.setText(displayName);
-        mTitle.setCustomSelectionActionModeCallback(
-                new HeaderTextSelector(mTitle, this::selectText));
-    }
-
-    private void selectText(Spannable text, int start, int stop) {
-        Selection.setSelection(text, start, stop);
     }
 
     private void loadHeaderImage(DocumentInfo doc) {
@@ -110,14 +99,10 @@
      */
     private void showImage(DocumentInfo info, @Nullable Bitmap thumbnail) {
         if (thumbnail != null) {
-            mThumbnail.resetPaddingToInitialValues();
             mThumbnail.setScaleType(ScaleType.CENTER_CROP);
             mThumbnail.setImageBitmap(thumbnail);
         } else {
-            mThumbnail.setPadding(0, 0, 0, mTitle.getHeight());
-
-            Drawable mimeIcon =
-                    mContext.getContentResolver().getTypeDrawable(info.mimeType);
+            Drawable mimeIcon = IconUtils.loadMimeIcon(mContext, info.mimeType);
             mThumbnail.setScaleType(ScaleType.FIT_CENTER);
             mThumbnail.setImageDrawable(mimeIcon);
         }
diff --git a/src/com/android/documentsui/inspector/InspectorActivity.java b/src/com/android/documentsui/inspector/InspectorActivity.java
index d02c43b..f7c2c8d 100644
--- a/src/com/android/documentsui/inspector/InspectorActivity.java
+++ b/src/com/android/documentsui/inspector/InspectorActivity.java
@@ -15,41 +15,66 @@
  */
 package com.android.documentsui.inspector;
 
-import android.app.Activity;
-import android.app.FragmentManager;
+import static androidx.core.util.Preconditions.checkArgument;
+
 import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.view.MenuItem;
-import android.view.Window;
-import android.widget.Toolbar;
+import android.view.View;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.loader.app.LoaderManager;
 
 import com.android.documentsui.R;
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.inspector.InspectorController.DataSupplier;
 
-public class InspectorActivity extends Activity {
+public class InspectorActivity extends AppCompatActivity {
 
-    private InspectorFragment mFragment;
+    private InspectorController mController;
+    private View mView;
+    private Toolbar mToolbar;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        requestWindowFeature(Window.FEATURE_ACTION_BAR);
+
+        // ToDo Create tool to check resource version before applyStyle for the theme
+        // If version code is not match, we should reset overlay package to default,
+        // in case Activity continueusly encounter resource not found exception
+        getTheme().applyStyle(R.style.DocumentsDefaultTheme, false);
+
         setContentView(R.layout.inspector_activity);
 
-        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
-        setActionBar(toolbar);
-        getActionBar().setDisplayHomeAsUpEnabled(true);
+        setContainer();
 
-        FragmentManager fragmentManager = getFragmentManager();
-        mFragment = (InspectorFragment) fragmentManager.findFragmentById(
-                R.id.fragment_container);
+        mToolbar = findViewById(R.id.toolbar);
+        setSupportActionBar(mToolbar);
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
-        if (mFragment == null) {
-            Intent intent = getIntent();
-            mFragment = InspectorFragment.newInstance(intent);
-            fragmentManager.beginTransaction()
-                    .add(R.id.fragment_container, mFragment)
-                    .commit();
-        }
+        final DataSupplier loader = new RuntimeDataSupplier(this, LoaderManager.getInstance(this));
+
+        mController = new InspectorController(this, loader, mView,
+                getIntent().getStringExtra(Intent.EXTRA_TITLE),
+                getIntent().getBooleanExtra(Shared.EXTRA_SHOW_DEBUG, false));
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        Uri uri = getIntent().getData();
+        checkArgument(uri.getScheme().equals("content"));
+        mController.loadInfo(uri);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mController.reset();
     }
 
     @Override
@@ -61,4 +86,27 @@
         }
         return super.onOptionsItemSelected(item);
     }
-}
+
+    private void setContainer() {
+        mView = findViewById(R.id.inspector_root);
+        mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        mView.setOnApplyWindowInsetsListener((v, insets) -> {
+            mView.setPadding(insets.getSystemWindowInsetLeft(),
+                    insets.getSystemWindowInsetTop(),
+                    insets.getSystemWindowInsetRight(), 0);
+
+            View container = findViewById(R.id.inspector_container);
+            container.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
+            return insets;
+        });
+
+        getWindow().setNavigationBarDividerColor(Color.TRANSPARENT);
+        if (Build.VERSION.SDK_INT >= 29) {
+            getWindow().setNavigationBarColor(Color.TRANSPARENT);
+            getWindow().setNavigationBarContrastEnforced(true);
+        } else {
+            getWindow().setNavigationBarColor(getColor(R.color.nav_bar_translucent));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/inspector/InspectorController.java b/src/com/android/documentsui/inspector/InspectorController.java
index 79612f9..291936a 100644
--- a/src/com/android/documentsui/inspector/InspectorController.java
+++ b/src/com/android/documentsui/inspector/InspectorController.java
@@ -15,9 +15,9 @@
  */
 package com.android.documentsui.inspector;
 
-import static com.android.internal.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 
-import android.annotation.StringRes;
+import androidx.annotation.StringRes;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -26,8 +26,8 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import android.view.View;
 import android.view.View.OnClickListener;
 
@@ -59,7 +59,8 @@
     private final PackageManager mPackageManager;
     private final ProvidersAccess mProviders;
     private final Runnable mErrorSnackbar;
-    private Bundle mArgs;
+    private final String mTitle;
+    private final boolean mShowDebug;
 
     /**
      * InspectorControllerTest relies on this controller.
@@ -76,7 +77,8 @@
             ActionDisplay showProvider,
             ActionDisplay appDefaults,
             DebugDisplay debugView,
-            Bundle args,
+            String title,
+            boolean showDebug,
             Runnable errorRunnable) {
 
         checkArgument(context != null);
@@ -89,7 +91,6 @@
         checkArgument(showProvider != null);
         checkArgument(appDefaults != null);
         checkArgument(debugView != null);
-        checkArgument(args != null);
         checkArgument(errorRunnable != null);
 
         mContext = context;
@@ -101,7 +102,8 @@
         mMedia = media;
         mShowProvider = showProvider;
         mAppDefaults = appDefaults;
-        mArgs = args;
+        mTitle = title;
+        mShowDebug = showDebug;
         mDebugView = debugView;
 
         mErrorSnackbar = errorRunnable;
@@ -111,11 +113,12 @@
      * @param activity
      * @param loader
      * @param layout
-     * @param args Bundle of arguments passed to our host {@link InspectorFragment}. These
+     * @param args Bundle of arguments passed to our host {@link InspectorActivity}. These
      *     can include extras that enable debug mode ({@link Shared#EXTRA_SHOW_DEBUG}
      *     and override the file title (@link {@link Intent#EXTRA_TITLE}).
      */
-    public InspectorController(Activity activity, DataSupplier loader, View layout, Bundle args) {
+    public InspectorController(Activity activity, DataSupplier loader, View layout,
+            String title, boolean showDebug) {
         this(activity,
             loader,
             activity.getPackageManager(),
@@ -126,14 +129,15 @@
             (ActionDisplay) layout.findViewById(R.id.inspector_show_in_provider_view),
             (ActionDisplay) layout.findViewById(R.id.inspector_app_defaults_view),
             (DebugView) layout.findViewById(R.id.inspector_debug_view),
-            args,
+            title,
+            showDebug,
             () -> {
                 // using a runnable to support unit testing this feature.
                 Snackbars.showInspectorError(activity);
             }
         );
 
-        if (args.getBoolean(Shared.EXTRA_SHOW_DEBUG)) {
+        if (showDebug) {
             DebugView view = (DebugView) layout.findViewById(R.id.inspector_debug_view);
             view.init(ProviderExecutor::forAuthority);
         }
@@ -154,8 +158,8 @@
         if (docInfo == null) {
             mErrorSnackbar.run();
         } else {
-            mHeader.accept(docInfo, mArgs.getString(Intent.EXTRA_TITLE, docInfo.displayName));
-            mDetails.accept(docInfo);
+            mHeader.accept(docInfo);
+            mDetails.accept(docInfo, mTitle != null ? mTitle : docInfo.displayName);
 
             if (docInfo.isDirectory()) {
                 mLoader.loadDirCount(docInfo, this::displayChildCount);
@@ -176,13 +180,6 @@
                     new ClearDefaultAppAction(mContext, mPackageManager, docInfo);
 
                 mAppDefaults.setVisible(defaultAction.canPerformAction());
-                if (defaultAction.canPerformAction()) {
-                    mAppDefaults.init(
-                        defaultAction,
-                        (View) -> {
-                            clearDefaultApp(defaultAction.getPackageName());
-                        });
-                }
             }
 
             if (docInfo.isMetadataSupported()) {
@@ -194,11 +191,10 @@
             }
             mMedia.setVisible(!mMedia.isEmpty());
 
-            if (mArgs.getBoolean(Shared.EXTRA_SHOW_DEBUG)) {
+            if (mShowDebug) {
                 mDebugView.accept(docInfo);
             }
-            mDebugView.setVisible(mArgs.getBoolean(Shared.EXTRA_SHOW_DEBUG)
-                    && !mDebugView.isEmpty());
+            mDebugView.setVisible(mShowDebug && !mDebugView.isEmpty());
         }
     }
 
@@ -220,7 +216,7 @@
 
         mMedia.accept(doc, metadata, geoClickListener);
 
-        if (mArgs.getBoolean(Shared.EXTRA_SHOW_DEBUG)) {
+        if (mShowDebug) {
             mDebugView.accept(metadata);
         }
     }
@@ -274,20 +270,6 @@
     }
 
     /**
-     * Clears the default app that's opens that file type.
-     *
-     * @param packageName of the preferred app.
-     */
-    public void clearDefaultApp(String packageName) {
-        assert packageName != null;
-        mPackageManager.clearPackagePreferredActivities(packageName);
-
-        mAppDefaults.setAppIcon(null);
-        mAppDefaults.setAppName(mContext.getString(R.string.handler_app_not_selected));
-        mAppDefaults.showAction(false);
-    }
-
-    /**
      * Interface for loading all the various forms of document data. This primarily
      * allows us to easily supply test data in tests.
      */
@@ -357,7 +339,7 @@
      * Provides details about a file.
      */
     public interface HeaderDisplay {
-        void accept(DocumentInfo info, String displayName);
+        void accept(DocumentInfo info);
     }
 
     /**
@@ -365,7 +347,7 @@
      */
     public interface DetailsDisplay {
 
-        void accept(DocumentInfo info);
+        void accept(DocumentInfo info, String displayName);
 
         void setChildrenCount(int count);
     }
diff --git a/src/com/android/documentsui/inspector/InspectorFragment.java b/src/com/android/documentsui/inspector/InspectorFragment.java
deleted file mode 100644
index b2fd155..0000000
--- a/src/com/android/documentsui/inspector/InspectorFragment.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.inspector;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.app.Fragment;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ScrollView;
-
-import com.android.documentsui.R;
-import com.android.documentsui.inspector.InspectorController.DataSupplier;
-
-/**
- * Displays the Properties view in Files.
- */
-public class InspectorFragment extends Fragment {
-
-    private static final String DOC_URI_ARG = "docUri";
-    private InspectorController mController;
-    private ScrollView mView;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-        Bundle savedInstanceState) {
-        final DataSupplier loader = new RuntimeDataSupplier(getActivity(), getLoaderManager());
-
-        mView = (ScrollView) inflater.inflate(R.layout.inspector_fragment,
-                container, false);
-        mController = new InspectorController(getActivity(), loader, mView, getArguments());
-        return mView;
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        Uri uri = (Uri) getArguments().get(DOC_URI_ARG);
-        mController.loadInfo(uri);
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        mController.reset();
-    }
-
-    /**
-     * Creates a fragment with the appropriate args.
-     */
-    public static InspectorFragment newInstance(Intent intent) {
-
-        Bundle extras = intent.getExtras();
-        extras = extras != null ? extras : Bundle.EMPTY;
-        Bundle args = extras.deepCopy();
-
-        Uri uri = intent.getData();
-        checkArgument(uri.getScheme().equals("content"));
-        args.putParcelable(DOC_URI_ARG, uri);
-
-        InspectorFragment fragment = new InspectorFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-}
diff --git a/src/com/android/documentsui/inspector/KeyValueRow.java b/src/com/android/documentsui/inspector/KeyValueRow.java
index 48801d5..00ef819 100644
--- a/src/com/android/documentsui/inspector/KeyValueRow.java
+++ b/src/com/android/documentsui/inspector/KeyValueRow.java
@@ -15,12 +15,11 @@
  */
 package com.android.documentsui.inspector;
 
-import android.annotation.StringRes;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Paint;
-import android.support.annotation.Nullable;
 import android.text.Selection;
 import android.text.Spannable;
 import android.util.AttributeSet;
@@ -29,6 +28,9 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+
 import com.android.documentsui.R;
 
 /**
@@ -87,10 +89,20 @@
     }
 
     @Override
+    public boolean hasOnClickListeners() {
+        TextView value = findViewById(R.id.table_row_value);
+        return value.hasOnClickListeners();
+    }
+
+    @Override
     public void setOnClickListener(OnClickListener callback) {
         TextView clickable = ((TextView) findViewById(R.id.table_row_value));
         mDefaultTextColor = clickable.getTextColors();
-        clickable.setTextColor(R.color.inspector_link);
+        TypedArray ta = getContext().obtainStyledAttributes(R.styleable.TextAppearance);
+        int linkColor = ta.getColor(R.styleable.TextAppearance_android_textColorLink,
+                mDefaultTextColor.getDefaultColor());
+        ta.recycle();
+        clickable.setTextColor(linkColor);
         clickable.setPaintFlags(clickable.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
         clickable.setOnClickListener(callback);
     }
@@ -102,5 +114,6 @@
         }
         reset.setPaintFlags(reset.getPaintFlags() & ~Paint.UNDERLINE_TEXT_FLAG);
         reset.setOnClickListener(null);
+        reset.setClickable(false);
     }
 }
diff --git a/src/com/android/documentsui/inspector/MediaView.java b/src/com/android/documentsui/inspector/MediaView.java
index b2ae758..502df24 100644
--- a/src/com/android/documentsui/inspector/MediaView.java
+++ b/src/com/android/documentsui/inspector/MediaView.java
@@ -24,7 +24,7 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 
@@ -65,7 +65,7 @@
 
     @Override
     public void accept(DocumentInfo doc, Bundle metadata, @Nullable Runnable geoClickListener) {
-        setTitle(R.string.inspector_metadata_section, true);
+        putTitle("", true);
 
         Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
         if (exif != null) {
diff --git a/src/com/android/documentsui/inspector/MetadataLoader.java b/src/com/android/documentsui/inspector/MetadataLoader.java
index 3de15ba..3d12d4e 100644
--- a/src/com/android/documentsui/inspector/MetadataLoader.java
+++ b/src/com/android/documentsui/inspector/MetadataLoader.java
@@ -15,12 +15,13 @@
  */
 package com.android.documentsui.inspector;
 
-import android.content.AsyncTaskLoader;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
+import androidx.loader.content.AsyncTaskLoader;
+
 import android.util.Log;
 
 import java.io.FileNotFoundException;
@@ -47,7 +48,7 @@
     public Bundle loadInBackground() {
         try {
             return DocumentsContract.getDocumentMetadata(mContext.getContentResolver(), mUri);
-        } catch (FileNotFoundException e) {
+        } catch (FileNotFoundException | RuntimeException e) {
             Log.e(TAG, "Failed to load metadata for doc: " + mUri, e);
         }
 
diff --git a/src/com/android/documentsui/inspector/MetadataUtils.java b/src/com/android/documentsui/inspector/MetadataUtils.java
index b5c1034..0307b94 100644
--- a/src/com/android/documentsui/inspector/MetadataUtils.java
+++ b/src/com/android/documentsui/inspector/MetadataUtils.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.inspector;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
+import static androidx.core.util.Preconditions.checkNotNull;
 
 import android.media.ExifInterface;
 import android.os.Bundle;
@@ -76,8 +76,7 @@
         String lonRef = exif.getString(ExifInterface.TAG_GPS_LONGITUDE_REF);
 
         return new float[] {
-            ExifInterface.convertRationalLatLonToFloat(lat, latRef),
-            ExifInterface.convertRationalLatLonToFloat(lon, lonRef)
+            convertRationalLatLonToFloat(lat, latRef), convertRationalLatLonToFloat(lon, lonRef)
         };
     }
 
@@ -88,4 +87,33 @@
                 data.getFloat(Shared.METADATA_VIDEO_LONGITUTE)
         };
     }
+
+    /** This founction is copied from {@link ExifInterface} */
+    private static float convertRationalLatLonToFloat(String rationalString, String ref) {
+        try {
+            String [] parts = rationalString.split(",");
+
+            String [] pair;
+            pair = parts[0].split("/");
+            double degrees = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
+
+            pair = parts[1].split("/");
+            double minutes = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
+
+            pair = parts[2].split("/");
+            double seconds = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
+
+            double result = degrees + (minutes / 60.0) + (seconds / 3600.0);
+            if ((ref.equals("S") || ref.equals("W"))) {
+                return (float) -result;
+            }
+            return (float) result;
+        } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
+            // Not valid
+            throw new IllegalArgumentException();
+        }
+    }
 }
diff --git a/src/com/android/documentsui/inspector/RuntimeDataSupplier.java b/src/com/android/documentsui/inspector/RuntimeDataSupplier.java
index e6cbda9..a7bac81 100644
--- a/src/com/android/documentsui/inspector/RuntimeDataSupplier.java
+++ b/src/com/android/documentsui/inspector/RuntimeDataSupplier.java
@@ -15,12 +15,9 @@
  */
 package com.android.documentsui.inspector;
 
-import static com.android.internal.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
 import android.content.Context;
-import android.content.CursorLoader;
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
@@ -28,7 +25,11 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
+import androidx.loader.app.LoaderManager;
+import androidx.loader.app.LoaderManager.LoaderCallbacks;
+import androidx.loader.content.CursorLoader;
+import androidx.loader.content.Loader;
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.inspector.InspectorController.DataSupplier;
@@ -109,17 +110,17 @@
     public void getDocumentMetadata(Uri uri, Consumer<Bundle> callback) {
         mMetadataCallbacks = new LoaderCallbacks<Bundle>() {
             @Override
-            public android.content.Loader<Bundle> onCreateLoader(int id, Bundle unused) {
+            public Loader<Bundle> onCreateLoader(int id, Bundle unused) {
                 return new MetadataLoader(mContext, uri);
             }
 
             @Override
-            public void onLoadFinished(android.content.Loader<Bundle> loader, Bundle data) {
+            public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
                 callback.accept(data);
             }
 
             @Override
-            public void onLoaderReset(android.content.Loader<Bundle> loader) {
+            public void onLoaderReset(Loader<Bundle> loader) {
             }
         };
 
@@ -173,12 +174,12 @@
         }
 
         @Override
-        public android.content.Loader<Cursor> onCreateLoader(int id, Bundle args) {
+        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
             return new CursorLoader(mContext, mUri, null, null, null, null);
         }
 
         @Override
-        public void onLoadFinished(android.content.Loader<Cursor> loader, Cursor cursor) {
+        public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
 
             if (cursor != null) {
                 mObserver = new InspectorContentObserver(loader::onContentChanged);
@@ -189,7 +190,7 @@
         }
 
         @Override
-        public void onLoaderReset(android.content.Loader<Cursor> loader) {
+        public void onLoaderReset(Loader<Cursor> loader) {
             if (mObserver != null) {
                 mContext.getContentResolver().unregisterContentObserver(mObserver);
             }
diff --git a/src/com/android/documentsui/inspector/TableView.java b/src/com/android/documentsui/inspector/TableView.java
index 191e89a..b259773 100644
--- a/src/com/android/documentsui/inspector/TableView.java
+++ b/src/com/android/documentsui/inspector/TableView.java
@@ -15,9 +15,10 @@
  */
 package com.android.documentsui.inspector;
 
-import android.annotation.StringRes;
 import android.content.Context;
 import android.content.res.Resources;
+import android.text.Selection;
+import android.text.Spannable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -26,6 +27,8 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.StringRes;
+
 import com.android.documentsui.R;
 import com.android.documentsui.inspector.InspectorController.TableDisplay;
 
@@ -60,7 +63,7 @@
     }
 
     void setTitle(@StringRes int title, boolean showDivider) {
-        putTitle(mContext.getResources().getString(title), showDivider);
+        putTitle(mRes.getString(title), showDivider);
     }
 
     // A naughty title method (that takes strings, not message ids), mostly for DebugView.
@@ -77,6 +80,13 @@
             mTitles.put(title, view);
         }
         view.setText(title);
+        view.setCustomSelectionActionModeCallback(
+                new HeaderTextSelector(view, this::selectText));
+        view.setVisibility(title.toString().isEmpty() ? GONE : VISIBLE);
+    }
+
+    private void selectText(Spannable text, int start, int stop) {
+        Selection.setSelection(text, start, stop);
     }
 
     protected KeyValueRow createKeyValueRow(ViewGroup parent) {
@@ -94,7 +104,6 @@
         put(mRes.getString(keyId), value);
     }
 
-
     /**
      * Puts or updates a value in the table view.
      */
@@ -105,7 +114,7 @@
             row = createKeyValueRow(this);
             row.setKey(key);
             mRows.put(key, row);
-        } else {
+        } else if (row.hasOnClickListeners()) {
             row.removeOnClickListener();
         }
 
diff --git a/src/com/android/documentsui/inspector/actions/Action.java b/src/com/android/documentsui/inspector/actions/Action.java
index d90d6dc..2d97c64 100644
--- a/src/com/android/documentsui/inspector/actions/Action.java
+++ b/src/com/android/documentsui/inspector/actions/Action.java
@@ -16,8 +16,8 @@
 
 package com.android.documentsui.inspector.actions;
 
-import android.annotation.Nullable;
-import android.annotation.StringRes;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
diff --git a/src/com/android/documentsui/inspector/actions/ActionView.java b/src/com/android/documentsui/inspector/actions/ActionView.java
index b519bcc..398a6b6 100644
--- a/src/com/android/documentsui/inspector/actions/ActionView.java
+++ b/src/com/android/documentsui/inspector/actions/ActionView.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.inspector.actions;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
diff --git a/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java b/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java
index f8f6aeb..c57237c 100644
--- a/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java
+++ b/src/com/android/documentsui/inspector/actions/ClearDefaultAppAction.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.inspector.actions;
 
-import android.annotation.StringRes;
+import androidx.annotation.StringRes;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -55,22 +55,7 @@
      */
     @Override
     public boolean canPerformAction() {
-        Intent intent = new Intent(Intent.ACTION_VIEW, mDoc.derivedUri);
-        List<ResolveInfo> list = mPm.queryIntentActivities(intent,
-            PackageManager.MATCH_DEFAULT_ONLY);
-
-        if (list.size() > 1) {
-            String packageName = getPackageName();
-            if (packageName == null) {
-                return false;
-            } else if (APP_NOT_CHOSEN.equals(packageName)) {
-                return false;
-            } else {
-                return true;
-            }
-        } else {
-            return false;
-        }
+        return false;
     }
 
     @Override
diff --git a/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java b/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java
index 0dc221a..1523ae7 100644
--- a/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java
+++ b/src/com/android/documentsui/inspector/actions/ShowInProviderAction.java
@@ -20,7 +20,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 
-import android.support.annotation.StringRes;
+import androidx.annotation.StringRes;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.roots.ProvidersAccess;
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index 4511fef..ef16e6d 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -23,11 +23,10 @@
 import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
 import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
 
-import android.app.Activity;
-import android.app.FragmentManager;
 import android.content.ClipData;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.QuickViewConstants;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -36,10 +35,16 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+
 import com.android.documentsui.AbstractActionHandler;
 import com.android.documentsui.ActivityConfig;
 import com.android.documentsui.DocumentsAccess;
 import com.android.documentsui.Injector;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.Model;
 import com.android.documentsui.base.BooleanConsumer;
@@ -51,12 +56,11 @@
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.AnimationView;
+import com.android.documentsui.files.QuickViewIntentBuilder;
 import com.android.documentsui.picker.ActionHandler.Addons;
 import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.roots.ProvidersAccess;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.services.FileOperationService;
-import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.Arrays;
 import java.util.concurrent.Executor;
@@ -66,31 +70,37 @@
 /**
  * Provides {@link PickActivity} action specializations to fragments.
  */
-class ActionHandler<T extends Activity & Addons> extends AbstractActionHandler<T> {
+class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionHandler<T> {
 
     private static final String TAG = "PickerActionHandler";
+    private static final String[] PREVIEW_FEATURES = {
+            QuickViewConstants.FEATURE_VIEW
+    };
 
     private final Features mFeatures;
     private final ActivityConfig mConfig;
     private final Model mModel;
     private final LastAccessedStorage mLastAccessed;
 
-    ActionHandler(
-            T activity,
-            State state,
-            ProvidersAccess providers,
-            DocumentsAccess docs,
-            SearchViewManager searchMgr,
-            Lookup<String, Executor> executors,
-            Injector injector,
-            LastAccessedStorage lastAccessed) {
+    private UpdatePickResultTask mUpdatePickResultTask;
 
+    ActionHandler(
+        T activity,
+        State state,
+        ProvidersAccess providers,
+        DocumentsAccess docs,
+        SearchViewManager searchMgr,
+        Lookup<String, Executor> executors,
+        Injector injector,
+        LastAccessedStorage lastAccessed) {
         super(activity, state, providers, docs, searchMgr, executors, injector);
 
         mConfig = injector.config;
         mFeatures = injector.features;
         mModel = injector.getModel();
         mLastAccessed = lastAccessed;
+        mUpdatePickResultTask = new UpdatePickResultTask(
+            activity.getApplicationContext(), mInjector.pickResult);
     }
 
     @Override
@@ -100,7 +110,9 @@
         // stack is initialized if it's restored from bundle, which means we're restoring a
         // previously stored state.
         if (mState.stack.isInitialized()) {
-            if (DEBUG) Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
+            if (DEBUG) {
+                Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
+            }
             restoreRootAndDirectory();
             return;
         }
@@ -110,16 +122,22 @@
         mActivity.setTitle("");
 
         if (launchHomeForCopyDestination(intent)) {
-            if (DEBUG) Log.d(TAG, "Launching directly into Home directory for copy destination.");
+            if (DEBUG) {
+                Log.d(TAG, "Launching directly into Home directory for copy destination.");
+            }
             return;
         }
 
-        if (mFeatures.isLaunchToDocumentEnabled() && launchToDocument(intent)) {
-            if (DEBUG) Log.d(TAG, "Launched to a document.");
+        if (mFeatures.isLaunchToDocumentEnabled() && launchToInitialUri(intent)) {
+            if (DEBUG) {
+                Log.d(TAG, "Launched to initial uri.");
+            }
             return;
         }
 
-        if (DEBUG) Log.d(TAG, "Load last accessed stack.");
+        if (DEBUG) {
+            Log.d(TAG, "Load last accessed stack.");
+        }
         loadLastAccessedStack();
     }
 
@@ -142,17 +160,24 @@
         return false;
     }
 
-    private boolean launchToDocument(Intent intent) {
+    private boolean launchToInitialUri(Intent intent) {
         Uri uri = intent.getParcelableExtra(DocumentsContract.EXTRA_INITIAL_URI);
         if (uri != null) {
-            return launchToDocument(uri);
+            if (DocumentsContract.isRootUri(mActivity, uri)) {
+                loadRoot(uri);
+                return true;
+            } else if (DocumentsContract.isDocumentUri(mActivity, uri)) {
+                return launchToDocument(uri);
+            }
         }
 
         return false;
     }
 
     private void loadLastAccessedStack() {
-        if (DEBUG) Log.d(TAG, "Attempting to load last used stack for calling package.");
+        if (DEBUG) {
+            Log.d(TAG, "Attempting to load last used stack for calling package.");
+        }
         new LoadLastAccessedStackTask<>(
                 mActivity, mLastAccessed, mState, mProviders, this::onLastAccessedStackLoaded)
                 .execute();
@@ -167,16 +192,44 @@
         }
     }
 
+    public UpdatePickResultTask getUpdatePickResultTask() {
+        return mUpdatePickResultTask;
+    }
+
+    private void updatePickResult(Intent intent, boolean isSearching, int root) {
+        ClipData cdata = intent.getClipData();
+        int fileCount = 0;
+        Uri uri = null;
+
+        // There are 2 cases that would be single-select:
+        // 1. getData() isn't null and getClipData() is null.
+        // 2. getClipData() isn't null and the item count of it is 1.
+        if (intent.getData() != null && cdata == null) {
+            fileCount = 1;
+            uri = intent.getData();
+        } else if (cdata != null) {
+            fileCount = cdata.getItemCount();
+            if (fileCount == 1) {
+                uri = cdata.getItemAt(0).getUri();
+            }
+        }
+
+        mInjector.pickResult.setFileCount(fileCount);
+        mInjector.pickResult.setIsSearching(isSearching);
+        mInjector.pickResult.setRoot(root);
+        mInjector.pickResult.setFileUri(uri);
+        getUpdatePickResultTask().execute();
+    }
+
     private void loadDefaultLocation() {
         switch (mState.action) {
             case ACTION_CREATE:
+            case ACTION_OPEN_TREE:
                 loadHomeDir();
                 break;
             case ACTION_GET_CONTENT:
             case ACTION_OPEN:
-            case ACTION_OPEN_TREE:
-                mState.stack.changeRoot(mProviders.getRecentsRoot());
-                mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
+                loadRecent();
                 break;
             default:
                 throw new UnsupportedOperationException("Unexpected action type: " + mState.action);
@@ -185,6 +238,7 @@
 
     @Override
     public void showAppDetails(ResolveInfo info) {
+        mInjector.pickResult.increaseActionCount();
         final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
         intent.setData(Uri.fromParts("package", info.activityInfo.packageName, null));
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
@@ -193,7 +247,9 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (DEBUG) Log.d(TAG, "onActivityResult() code=" + resultCode);
+        if (DEBUG) {
+            Log.d(TAG, "onActivityResult() code=" + resultCode);
+        }
 
         // Only relay back results when not canceled; otherwise stick around to
         // let the user pick another app/backend.
@@ -207,10 +263,12 @@
     }
 
     private void onExternalAppResult(int resultCode, Intent data) {
-        if (resultCode != Activity.RESULT_CANCELED) {
+        if (resultCode != FragmentActivity.RESULT_CANCELED) {
             // Remember that we last picked via external app
             mLastAccessed.setLastAccessedToExternalApp(mActivity);
 
+            updatePickResult(data, false, MetricConsts.ROOT_THIRD_PARTY_APP);
+
             // Pass back result to original caller
             mActivity.setResult(resultCode, data, 0);
             mActivity.finish();
@@ -227,13 +285,15 @@
 
     @Override
     public void openRoot(RootInfo root) {
-        Metrics.logRootVisited(mActivity, Metrics.PICKER_SCOPE, root);
+        Metrics.logRootVisited(MetricConsts.PICKER_SCOPE, root);
+        mInjector.pickResult.increaseActionCount();
         mActivity.onRootPicked(root);
     }
 
     @Override
     public void openRoot(ResolveInfo info) {
-        Metrics.logAppVisited(mActivity, info);
+        Metrics.logAppVisited(info);
+        mInjector.pickResult.increaseActionCount();
         final Intent intent = new Intent(mActivity.getIntent());
         intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
         intent.setComponent(new ComponentName(
@@ -246,44 +306,83 @@
     }
 
     @Override
-    public boolean openItem(ItemDetails details, @ViewType int type,
+    public boolean openItem(ItemDetails<String> details, @ViewType int type,
             @ViewType int fallback) {
-        DocumentInfo doc = mModel.getDocument(details.getStableId());
+        mInjector.pickResult.increaseActionCount();
+        DocumentInfo doc = mModel.getDocument(details.getSelectionKey());
         if (doc == null) {
-            Log.w(TAG,
-                    "Can't view item. No Document available for modeId: " + details.getStableId());
+            Log.w(TAG, "Can't view item. No Document available for modeId: "
+                    + details.getSelectionKey());
             return false;
         }
 
         if (mConfig.isDocumentEnabled(doc.mimeType, doc.flags, mState)) {
             mActivity.onDocumentPicked(doc);
             mSelectionMgr.clearSelection();
-            return true;
+            return !doc.isDirectory();
         }
         return false;
     }
 
-    void pickDocument(DocumentInfo pickTarget) {
+    @Override
+    public boolean previewItem(ItemDetails<String> details) {
+        mInjector.pickResult.increaseActionCount();
+        final DocumentInfo doc = mModel.getDocument(details.getSelectionKey());
+        if (doc == null) {
+            Log.w(TAG, "Can't view item. No Document available for modeId: "
+                    + details.getSelectionKey());
+            return false;
+        }
+        return priviewDocument(doc);
+
+    }
+
+    @VisibleForTesting
+    boolean priviewDocument(DocumentInfo doc) {
+        Intent intent = new QuickViewIntentBuilder(
+                mActivity.getPackageManager(),
+                mActivity.getResources(),
+                doc,
+                mModel,
+                true /* fromPicker */).build();
+
+        if (intent != null) {
+            try {
+                mActivity.startActivity(intent);
+                return true;
+            } catch (SecurityException e) {
+                Log.e(TAG, "Caught security error: " + e.getLocalizedMessage());
+            }
+        } else {
+            Log.e(TAG, "Quick view intetn is null");
+        }
+
+        mInjector.dialogs.showNoApplicationFound();
+        return false;
+    }
+
+    void pickDocument(FragmentManager fm, DocumentInfo pickTarget) {
         assert(pickTarget != null);
+        mInjector.pickResult.increaseActionCount();
         Uri result;
         switch (mState.action) {
             case ACTION_OPEN_TREE:
-                result = DocumentsContract.buildTreeDocumentUri(
-                        pickTarget.authority, pickTarget.documentId);
+                mInjector.dialogs.confirmAction(fm, pickTarget, ConfirmFragment.TYPE_OEPN_TREE);
                 break;
             case ACTION_PICK_COPY_DESTINATION:
                 result = pickTarget.derivedUri;
+                finishPicking(result);
                 break;
             default:
                 // Should not be reached
                 throw new IllegalStateException("Invalid mState.action");
         }
-        finishPicking(result);
     }
 
     void saveDocument(
             String mimeType, String displayName, BooleanConsumer inProgressStateListener) {
         assert(mState.action == ACTION_CREATE);
+        mInjector.pickResult.increaseActionCount();
         new CreatePickedDocumentTask(
                 mActivity,
                 mDocs,
@@ -300,12 +399,13 @@
     // called.
     void saveDocument(FragmentManager fm, DocumentInfo replaceTarget) {
         assert(mState.action == ACTION_CREATE);
+        mInjector.pickResult.increaseActionCount();
         assert(replaceTarget != null);
 
         // Adding a confirmation dialog breaks an inherited CTS test (testCreateExisting), so we
         // need to add a feature flag to bypass this feature in ARC++ environment.
         if (mFeatures.isOverwriteConfirmationEnabled()) {
-            mInjector.dialogs.confirmOverwrite(fm, replaceTarget);
+            mInjector.dialogs.confirmAction(fm, replaceTarget, ConfirmFragment.TYPE_OVERWRITE);
         } else {
             finishPicking(replaceTarget.derivedUri);
         }
@@ -323,7 +423,9 @@
     }
 
     private void onPickFinished(Uri... uris) {
-        if (DEBUG) Log.d(TAG, "onFinished() " + Arrays.toString(uris));
+        if (DEBUG) {
+            Log.d(TAG, "onFinished() " + Arrays.toString(uris));
+        }
 
         final Intent intent = new Intent();
         if (uris.length == 1) {
@@ -337,6 +439,9 @@
             intent.setClipData(clipData);
         }
 
+        updatePickResult(
+            intent, mSearchMgr.isSearching(), Metrics.sanitizeRoot(mState.stack.getRoot()));
+
         // TODO: Separate this piece of logic per action.
         // We don't instantiate different objects for different actions at the first place, so it's
         // not a easy task to separate this logic cleanly.
@@ -360,7 +465,7 @@
                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
         }
 
-        mActivity.setResult(Activity.RESULT_OK, intent, 0);
+        mActivity.setResult(FragmentActivity.RESULT_OK, intent, 0);
         mActivity.finish();
     }
 
@@ -378,8 +483,8 @@
         void onDocumentPicked(DocumentInfo doc);
 
         /**
-         * Overload final method {@link Activity#setResult(int, Intent)} so that we can intercept
-         * this method call in test environment.
+         * Overload final method {@link FragmentActivity#setResult(int, Intent)} so that we can
+         * intercept this method call in test environment.
          */
         @VisibleForTesting
         void setResult(int resultCode, Intent result, int notUsed);
diff --git a/src/com/android/documentsui/picker/Config.java b/src/com/android/documentsui/picker/Config.java
index 959da9f..299d639 100644
--- a/src/com/android/documentsui/picker/Config.java
+++ b/src/com/android/documentsui/picker/Config.java
@@ -61,6 +61,8 @@
         }
 
         switch (state.action) {
+            case ACTION_PICK_COPY_DESTINATION:
+                return false;
             case ACTION_CREATE:
                 // Read-only files are disabled when creating.
                 if ((docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
diff --git a/src/com/android/documentsui/picker/ConfirmFragment.java b/src/com/android/documentsui/picker/ConfirmFragment.java
new file mode 100644
index 0000000..f56434d
--- /dev/null
+++ b/src/com/android/documentsui/picker/ConfirmFragment.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2019 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.documentsui.picker;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.text.TextUtils;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.R;
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Shared;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
+/**
+ * Used to confirm with user that it's OK to overwrite an existing file.
+ */
+public class ConfirmFragment extends DialogFragment {
+
+    private static final String TAG = "ConfirmFragment";
+
+    public static final String CONFIRM_TYPE = "type";
+    public static final int TYPE_OVERWRITE = 1;
+    public static final int TYPE_OEPN_TREE = 2;
+
+    private ActionHandler<PickActivity> mActions;
+    private DocumentInfo mTarget;
+    private int mType;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        mActions = ((PickActivity) getActivity()).getInjector().actions;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Bundle arg = (getArguments() != null) ? getArguments() : savedInstanceState;
+
+        mTarget = arg.getParcelable(Shared.EXTRA_DOC);
+        mType = arg.getInt(CONFIRM_TYPE);
+        final PickResult pickResult = ((PickActivity) getActivity()).getInjector().pickResult;
+
+        final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
+        switch (mType) {
+            case TYPE_OVERWRITE:
+                String message = String.format(
+                        getString(R.string.overwrite_file_confirmation_message),
+                        mTarget.displayName);
+                builder.setMessage(message);
+                builder.setPositiveButton(
+                        android.R.string.ok,
+                        (DialogInterface dialog, int id) -> {
+                            pickResult.increaseActionCount();
+                            mActions.finishPicking(mTarget.derivedUri);
+                        });
+                break;
+            case TYPE_OEPN_TREE:
+                final Uri uri = DocumentsContract.buildTreeDocumentUri(
+                        mTarget.authority, mTarget.documentId);
+                final BaseActivity activity = (BaseActivity) getActivity();
+                final String target = activity.getCurrentTitle();
+                final String location = activity.getCurrentRoot().title;
+                final String text = getString(R.string.open_tree_dialog_title, target, location);
+                message = getString(R.string.open_tree_dialog_message,
+                        getAppName(getActivity().getCallingPackage()));
+
+                builder.setTitle(text);
+                builder.setMessage(message);
+                builder.setPositiveButton(
+                        R.string.allow,
+                        (DialogInterface dialog, int id) -> {
+                            pickResult.increaseActionCount();
+                            mActions.finishPicking(uri);
+                        });
+                break;
+
+        }
+        builder.setNegativeButton(android.R.string.cancel,
+                (DialogInterface dialog, int id) -> pickResult.increaseActionCount());
+
+        return builder.create();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putParcelable(Shared.EXTRA_DOC, mTarget);
+        outState.putInt(CONFIRM_TYPE, mType);
+    }
+
+    private String getAppName(String packageName) {
+        final String anonymous = getString(R.string.anonymous_application);
+        if (TextUtils.isEmpty(packageName)) {
+            return anonymous;
+        }
+
+        final PackageManager pm = getContext().getPackageManager();
+        ApplicationInfo ai;
+        try {
+            ai = pm.getApplicationInfo(packageName, 0);
+        } catch (final PackageManager.NameNotFoundException e) {
+            return anonymous;
+        }
+
+        CharSequence result = pm.getApplicationLabel(ai);
+        return TextUtils.isEmpty(result) ? anonymous : result.toString();
+    }
+
+    public static void show(FragmentManager fm, DocumentInfo overwriteTarget, int type) {
+        Bundle arg = new Bundle();
+        arg.putParcelable(Shared.EXTRA_DOC, overwriteTarget);
+        arg.putInt(CONFIRM_TYPE, type);
+
+        FragmentTransaction ft = fm.beginTransaction();
+        Fragment f = new ConfirmFragment();
+        f.setArguments(arg);
+        ft.add(f, TAG);
+        ft.commitAllowingStateLoss();
+    }
+}
diff --git a/src/com/android/documentsui/picker/CreatePickedDocumentTask.java b/src/com/android/documentsui/picker/CreatePickedDocumentTask.java
index 25c57f2..a478d7c 100644
--- a/src/com/android/documentsui/picker/CreatePickedDocumentTask.java
+++ b/src/com/android/documentsui/picker/CreatePickedDocumentTask.java
@@ -21,9 +21,10 @@
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.provider.DocumentsContract;
-import android.support.design.widget.Snackbar;
 import android.util.Log;
 
+import com.google.android.material.snackbar.Snackbar;
+
 import com.android.documentsui.DocumentsAccess;
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.R;
diff --git a/src/com/android/documentsui/picker/LastAccessedProvider.java b/src/com/android/documentsui/picker/LastAccessedProvider.java
index 20a9d0a..a382256 100644
--- a/src/com/android/documentsui/picker/LastAccessedProvider.java
+++ b/src/com/android/documentsui/picker/LastAccessedProvider.java
@@ -31,17 +31,16 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.FileUtils;
 import android.provider.DocumentsContract;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.DurableUtils;
 
-import libcore.io.IoUtils;
-
-import com.google.android.collect.Sets;
-
 import java.io.IOException;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Predicate;
 
@@ -190,10 +189,12 @@
         if (METHOD_PURGE.equals(method)) {
             // Purge references to unknown authorities
             final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE);
-            final Set<String> knownAuth = Sets.newHashSet();
+            final Set<String> knownAuth = new HashSet<>();
             for (ResolveInfo info : getContext()
                     .getPackageManager().queryIntentContentProviders(intent, 0)) {
-                knownAuth.add(info.providerInfo.authority);
+                if (info != null && !TextUtils.isEmpty(info.providerInfo.authority)) {
+                    knownAuth.add(info.providerInfo.authority);
+                }
             }
 
             purgeByAuthority(new Predicate<String>() {
@@ -210,7 +211,7 @@
             // Purge references to authorities in given package
             final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE);
             intent.setPackage(arg);
-            final Set<String> packageAuth = Sets.newHashSet();
+            final Set<String> packageAuth = new HashSet<>();
             for (ResolveInfo info : getContext()
                     .getPackageManager().queryIntentContentProviders(intent, 0)) {
                 packageAuth.add(info.providerInfo.authority);
@@ -259,7 +260,7 @@
                 }
             }
         } finally {
-            IoUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(cursor);
         }
     }
 }
diff --git a/src/com/android/documentsui/picker/LastAccessedStorage.java b/src/com/android/documentsui/picker/LastAccessedStorage.java
index ed38de0..b2b849b 100644
--- a/src/com/android/documentsui/picker/LastAccessedStorage.java
+++ b/src/com/android/documentsui/picker/LastAccessedStorage.java
@@ -28,7 +28,7 @@
 import com.android.documentsui.base.State;
 import com.android.documentsui.roots.ProvidersAccess;
 
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 
 import java.io.IOException;
 
@@ -69,7 +69,7 @@
             } catch (IOException e) {
                 Log.w(TAG, "Failed to resume: ", e);
             } finally {
-                IoUtils.closeQuietly(cursor);
+                FileUtils.closeQuietly(cursor);
             }
 
             return null;
diff --git a/src/com/android/documentsui/picker/MenuManager.java b/src/com/android/documentsui/picker/MenuManager.java
index d5fc8f2..b9e68ec 100644
--- a/src/com/android/documentsui/picker/MenuManager.java
+++ b/src/com/android/documentsui/picker/MenuManager.java
@@ -16,24 +16,32 @@
 
 package com.android.documentsui.picker;
 
+import static com.android.documentsui.base.DocumentInfo.getCursorString;
 import static com.android.documentsui.base.State.ACTION_CREATE;
 import static com.android.documentsui.base.State.ACTION_GET_CONTENT;
 import static com.android.documentsui.base.State.ACTION_OPEN;
 import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
 import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
 
+import android.database.Cursor;
+import android.provider.DocumentsContract.Document;
 import android.view.KeyboardShortcutGroup;
 import android.view.Menu;
 import android.view.MenuItem;
 
+import com.android.documentsui.Model;
+import com.android.documentsui.base.MimeTypes;
 import com.android.documentsui.base.State;
 import com.android.documentsui.queries.SearchViewManager;
 
 import java.util.List;
 import java.util.function.IntFunction;
+import com.android.documentsui.R;
 
 public final class MenuManager extends com.android.documentsui.MenuManager {
 
+    private boolean mOnlyDirectory;
+
     public MenuManager(SearchViewManager searchManager, State displayState, DirectoryDetails dirDetails) {
         super(searchManager, displayState, dirDetails);
 
@@ -62,6 +70,19 @@
     }
 
     @Override
+    public void updateModel(Model model) {
+        for (String id : model.getModelIds()) {
+            Cursor cursor = model.getItem(id);
+            String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+            if (!MimeTypes.mimeMatches(Document.MIME_TYPE_DIR, docMimeType)) {
+                mOnlyDirectory = false;
+                return;
+            }
+        }
+        mOnlyDirectory = true;
+    }
+
+    @Override
     protected void updateModePicker(MenuItem grid, MenuItem list) {
         // No display options in recent directories
         if (picking() && mDirDetails.isInRecents()) {
@@ -74,8 +95,9 @@
 
     @Override
     protected void updateSelectAll(MenuItem selectAll) {
-        boolean enabled = mState.allowMultiple;
-        selectAll.setVisible(enabled);
+        boolean visible = mState.allowMultiple;
+        boolean enabled = visible && !mOnlyDirectory;
+        selectAll.setVisible(visible);
         selectAll.setEnabled(enabled);
     }
 
@@ -86,18 +108,10 @@
     }
 
     @Override
-    protected void updateOpenInActionMode(MenuItem open, SelectionDetails selectionDetails) {
-        updateOpen(open, selectionDetails);
-    }
-
-    @Override
-    protected void updateOpenInContextMenu(MenuItem open, SelectionDetails selectionDetails) {
-        updateOpen(open, selectionDetails);
-    }
-
-    private void updateOpen(MenuItem open, SelectionDetails selectionDetails) {
-        open.setVisible(mState.action == ACTION_GET_CONTENT
+    protected void updateSelect(MenuItem select, SelectionDetails selectionDetails) {
+        select.setVisible(mState.action == ACTION_GET_CONTENT
                 || mState.action == ACTION_OPEN);
-        open.setEnabled(selectionDetails.size() > 0);
+        select.setEnabled(selectionDetails.size() > 0);
+        select.setTitle(R.string.menu_select);
     }
 }
diff --git a/src/com/android/documentsui/picker/OverwriteConfirmFragment.java b/src/com/android/documentsui/picker/OverwriteConfirmFragment.java
deleted file mode 100644
index e4cb623..0000000
--- a/src/com/android/documentsui/picker/OverwriteConfirmFragment.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.picker;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.DialogInterface;
-import android.os.Bundle;
-
-import com.android.documentsui.R;
-import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Shared;
-
-/**
- * Used to confirm with user that it's OK to overwrite an existing file.
- */
-public class OverwriteConfirmFragment extends DialogFragment {
-
-    private static final String TAG = "OverwriteConfirmFragment";
-
-    private ActionHandler<PickActivity> mActions;
-    private DocumentInfo mOverwriteTarget;
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        mActions = ((PickActivity) getActivity()).getInjector().actions;
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        Bundle arg = (getArguments() != null) ? getArguments() : savedInstanceState;
-
-        mOverwriteTarget = arg.getParcelable(Shared.EXTRA_DOC);
-
-        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        final String message = String.format(
-                getString(R.string.overwrite_file_confirmation_message),
-                mOverwriteTarget.displayName);
-        builder.setMessage(message);
-        builder.setPositiveButton(
-                android.R.string.ok,
-                (DialogInterface dialog, int id) ->
-                        mActions.finishPicking(mOverwriteTarget.derivedUri));
-        builder.setNegativeButton(android.R.string.cancel, null);
-
-        return builder.create();
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-
-        outState.putParcelable(Shared.EXTRA_DOC, mOverwriteTarget);
-    }
-
-    public static void show(FragmentManager fm, DocumentInfo overwriteTarget) {
-        Bundle arg = new Bundle();
-        arg.putParcelable(Shared.EXTRA_DOC, overwriteTarget);
-
-        FragmentTransaction ft = fm.beginTransaction();
-        Fragment f = new OverwriteConfirmFragment();
-        f.setArguments(arg);
-        ft.add(f, TAG);
-        ft.commitAllowingStateLoss();
-    }
-}
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index 94327b1..57969e0 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -22,15 +22,20 @@
 import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
 import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
 
-import android.app.Fragment;
-import android.app.FragmentManager;
 import android.content.Intent;
+import android.graphics.Color;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.provider.DocumentsContract;
-import android.support.annotation.CallSuper;
 import android.view.KeyEvent;
 import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+import androidx.annotation.CallSuper;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
 
 import com.android.documentsui.ActionModeController;
 import com.android.documentsui.BaseActivity;
@@ -39,6 +44,7 @@
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
 import com.android.documentsui.MenuManager.DirectoryDetails;
+import com.android.documentsui.Metrics;
 import com.android.documentsui.ProviderExecutor;
 import com.android.documentsui.R;
 import com.android.documentsui.SharedInputHandler;
@@ -48,6 +54,7 @@
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
+import com.android.documentsui.dirlist.AppsRowManager;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.prefs.ScopedPreferences;
 import com.android.documentsui.services.FileOperationService;
@@ -67,8 +74,6 @@
     private Injector<ActionHandler<PickActivity>> mInjector;
     private SharedInputHandler mSharedInputHandler;
 
-    private LastAccessedStorage mLastAccessed;
-
     public PickActivity() {
         super(R.layout.documents_activity, TAG);
     }
@@ -94,16 +99,14 @@
 
         super.onCreate(icicle);
 
-        mInjector.selectionMgr = mState.allowMultiple
-                ? DocsSelectionHelper.createMultiSelect()
-                : DocsSelectionHelper.createSingleSelect();
+        mInjector.selectionMgr = DocsSelectionHelper.create();
 
         mInjector.focusManager = new FocusManager(
                 mInjector.features,
                 mInjector.selectionMgr,
                 mDrawer,
                 this::focusSidebar,
-                getColor(R.color.accent_dark));
+                getColor(R.color.primary));
 
         mInjector.menuManager = new MenuManager(mSearchManager, mState, new DirectoryDetails(this));
 
@@ -113,7 +116,7 @@
                 mInjector.menuManager,
                 mInjector.messages);
 
-        mLastAccessed = LastAccessedStorage.create();
+        mInjector.pickResult = getPickResult(icicle);
         mInjector.actions = new ActionHandler<>(
                 this,
                 mState,
@@ -122,43 +125,87 @@
                 mSearchManager,
                 ProviderExecutor::forAuthority,
                 mInjector,
-                mLastAccessed);
+                LastAccessedStorage.create());
 
         mInjector.searchManager = mSearchManager;
 
         Intent intent = getIntent();
 
+        mAppsRowManager = new AppsRowManager(mInjector.actions);
+        mInjector.appsRowManager = mAppsRowManager;
+
         mSharedInputHandler =
                 new SharedInputHandler(
                         mInjector.focusManager,
                         mInjector.selectionMgr,
                         mInjector.searchManager::cancelSearch,
                         this::popDir,
-                        mInjector.features);
+                        mInjector.features,
+                        mDrawer);
         setupLayout(intent);
         mInjector.actions.initLocation(intent);
+        Metrics.logPickerLaunchedFrom(Shared.getCallingPackageName(this));
+    }
+
+    @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+        // log the case of user picking nothing.
+        mInjector.actions.getUpdatePickResultTask().execute();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle state) {
+        super.onSaveInstanceState(state);
+        state.putParcelable(Shared.EXTRA_PICK_RESULT, mInjector.pickResult);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mInjector.pickResult.setPickStartTime(SystemClock.uptimeMillis());
+    }
+
+    @Override
+    protected void onPause() {
+        mInjector.pickResult.increaseDuration(SystemClock.uptimeMillis());
+        super.onPause();
+    }
+
+    private static PickResult getPickResult(Bundle icicle) {
+        if (icicle != null) {
+            PickResult result = icicle.getParcelable(Shared.EXTRA_PICK_RESULT);
+            return result;
+        }
+
+        return new PickResult();
     }
 
     private void setupLayout(Intent intent) {
         if (mState.action == ACTION_CREATE) {
             final String mimeType = intent.getType();
             final String title = intent.getStringExtra(Intent.EXTRA_TITLE);
-            SaveFragment.show(getFragmentManager(), mimeType, title);
+            SaveFragment.show(getSupportFragmentManager(), mimeType, title);
         } else if (mState.action == ACTION_OPEN_TREE ||
                    mState.action == ACTION_PICK_COPY_DESTINATION) {
-            PickFragment.show(getFragmentManager());
+            PickFragment.show(getSupportFragmentManager());
+        } else {
+            // If PickFragment or SaveFragment does not show,
+            // Set save container background to transparent for edge to edge nav bar.
+            View saveContainer = findViewById(R.id.container_save);
+            saveContainer.setBackgroundColor(Color.TRANSPARENT);
         }
 
         if (mState.action == ACTION_GET_CONTENT) {
             final Intent moreApps = new Intent(intent);
             moreApps.setComponent(null);
             moreApps.setPackage(null);
-            RootsFragment.show(getFragmentManager(), moreApps);
+            RootsFragment.show(getSupportFragmentManager(), moreApps);
         } else if (mState.action == ACTION_OPEN ||
                    mState.action == ACTION_CREATE ||
                    mState.action == ACTION_OPEN_TREE ||
                    mState.action == ACTION_PICK_COPY_DESTINATION) {
-            RootsFragment.show(getFragmentManager(), (Intent) null);
+            RootsFragment.show(getSupportFragmentManager(), (Intent) null);
         }
     }
 
@@ -239,7 +286,7 @@
         final DocumentInfo cwd = getCurrentDirectory();
 
         if (mState.action == ACTION_CREATE) {
-            final FragmentManager fm = getFragmentManager();
+            final FragmentManager fm = getSupportFragmentManager();
             SaveFragment.get(fm).prepareForDirectory(cwd);
         }
 
@@ -247,8 +294,14 @@
     }
 
     @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        mInjector.pickResult.increaseActionCount();
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
     protected void refreshDirectory(int anim) {
-        final FragmentManager fm = getFragmentManager();
+        final FragmentManager fm = getSupportFragmentManager();
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
 
@@ -292,14 +345,16 @@
 
     @Override
     public void onDocumentPicked(DocumentInfo doc) {
-        final FragmentManager fm = getFragmentManager();
+        final FragmentManager fm = getSupportFragmentManager();
         // Do not inline-open archives, as otherwise it would be impossible to pick
         // archive files. Note, that picking files inside archives is not supported.
         if (doc.isDirectory()) {
             mInjector.actions.openContainerDocument(doc);
+            mSearchManager.recordHistory();
         } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
             // Explicit file picked, return
             mInjector.actions.finishPicking(doc.derivedUri);
+            mSearchManager.recordHistory();
         } else if (mState.action == ACTION_CREATE) {
             // Replace selected file
             SaveFragment.get(fm).setReplaceTarget(doc);
@@ -315,6 +370,7 @@
                 uris[i] = docs.get(i).derivedUri;
             }
             mInjector.actions.finishPicking(uris);
+            mSearchManager.recordHistory();
         }
     }
 
diff --git a/src/com/android/documentsui/picker/PickCountRecordProvider.java b/src/com/android/documentsui/picker/PickCountRecordProvider.java
new file mode 100644
index 0000000..0a8e215
--- /dev/null
+++ b/src/com/android/documentsui/picker/PickCountRecordProvider.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2019 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.documentsui.picker;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+import android.util.Log;
+
+public class PickCountRecordProvider extends ContentProvider {
+    private static final String TAG = "PickCountRecordProvider";
+
+    private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int URI_PICK_RECORD = 1;
+
+    private static final String PATH_PICK_COUNT_RECORD = "pickCountRecord";
+
+    private static final String TABLE_PICK_COUNT_RECORD = "pickCountRecordTable";
+
+    static final String AUTHORITY = "com.android.documentsui.pickCountRecord";
+
+    static {
+        MATCHER.addURI(AUTHORITY, "pickCountRecord/*", URI_PICK_RECORD);
+    }
+
+    public static class Columns {
+        public static final String FILE_HASH_ID = "file_hash_id";
+        public static final String PICK_COUNT = "pick_count";
+    }
+
+    /**
+     * Build pickRecord uri.
+     *
+     * @param hashFileId the file hash id.
+     * @return return an pick record uri.
+     */
+    public static Uri buildPickRecordUri(int hashFileId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(AUTHORITY).appendPath(PATH_PICK_COUNT_RECORD)
+                .appendPath(Integer.toString(hashFileId))
+                .build();
+    }
+
+    private PickCountRecordProvider.DatabaseHelper mHelper;
+
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String DB_NAME = "pickCountRecord.db";
+
+        private static final int VERSION_INIT = 1;
+
+        public DatabaseHelper(Context context) {
+            super(context, DB_NAME, null, VERSION_INIT);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE_PICK_COUNT_RECORD + " ("
+                    + PickCountRecordProvider.Columns.FILE_HASH_ID + " TEXT NOT NULL PRIMARY KEY,"
+                    + PickCountRecordProvider.Columns.PICK_COUNT + " INTEGER" + ")");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(TAG, "Upgrading database; wiping app data");
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_PICK_COUNT_RECORD);
+            onCreate(db);
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        mHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        if (MATCHER.match(uri) != URI_PICK_RECORD) {
+            throw new UnsupportedOperationException("Unsupported Uri " + uri);
+        }
+        final SQLiteDatabase db = mHelper.getReadableDatabase();
+        final String fileHashId = uri.getPathSegments().get(1);
+        return db.query(TABLE_PICK_COUNT_RECORD, projection, Columns.FILE_HASH_ID + "=?",
+                new String[] { fileHashId }, null, null, sortOrder);
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        if (MATCHER.match(uri) != URI_PICK_RECORD) {
+            throw new UnsupportedOperationException("Unsupported Uri " + uri);
+        }
+        final SQLiteDatabase db = mHelper.getWritableDatabase();
+        final ContentValues key = new ContentValues();
+
+        final String hashId = uri.getPathSegments().get(1);
+        key.put(Columns.FILE_HASH_ID, hashId);
+
+        // Ensure that row exists, then update with changed values
+        db.insertWithOnConflict(TABLE_PICK_COUNT_RECORD, null, key, SQLiteDatabase.CONFLICT_IGNORE);
+        db.update(TABLE_PICK_COUNT_RECORD, values, Columns.FILE_HASH_ID + "=?",
+            new String[] { hashId });
+        return null;
+    }
+
+    static void setPickRecord(ContentResolver resolver, int fileHashId, int pickCount) {
+        final ContentValues values = new ContentValues();
+        values.clear();
+        values.put(Columns.PICK_COUNT, pickCount);
+        resolver.insert(buildPickRecordUri(fileHashId), values);
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("Unsupported Uri " + uri);
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        final SQLiteDatabase db = mHelper.getWritableDatabase();
+        final String hashId = uri.getPathSegments().get(1);
+        return db.delete(TABLE_PICK_COUNT_RECORD, Columns.FILE_HASH_ID + "=?",
+            new String[] { hashId });
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/picker/PickCountRecordStorage.java b/src/com/android/documentsui/picker/PickCountRecordStorage.java
new file mode 100644
index 0000000..01476ee
--- /dev/null
+++ b/src/com/android/documentsui/picker/PickCountRecordStorage.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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.documentsui.picker;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+
+public interface PickCountRecordStorage {
+    int getPickCountRecord(Context context, Uri uri);
+    void setPickCountRecord(Context context, Uri uri, int pickCount);
+    int increasePickCountRecord(Context context, Uri uri);
+
+    static PickCountRecordStorage create() {
+        return new PickCountRecordStorage() {
+            private static final String TAG = "PickCountRecordStorage";
+
+            @Override
+            public int getPickCountRecord(Context context, Uri uri) {
+                int fileHashId = uri.hashCode();
+                Uri pickRecordUri = PickCountRecordProvider.buildPickRecordUri(fileHashId);
+                final ContentResolver resolver = context.getContentResolver();
+                int count = 0;
+                try (Cursor cursor = resolver.query(pickRecordUri, null, null, null, null)) {
+                    if (cursor != null && cursor.moveToFirst()) {
+                        final int index = cursor
+                            .getColumnIndex(PickCountRecordProvider.Columns.PICK_COUNT);
+                        if (index != -1) {
+                            count = cursor.getInt(index);
+                        }
+                    }
+                }
+                return count;
+            }
+
+            @Override
+            public void setPickCountRecord(Context context, Uri uri, int pickCount) {
+                PickCountRecordProvider.setPickRecord(
+                    context.getContentResolver(), uri.hashCode(), pickCount);
+            }
+
+            @Override
+            public int increasePickCountRecord(Context context, Uri uri) {
+                int pickCount = getPickCountRecord(context, uri) + 1;
+                setPickCountRecord(context, uri, pickCount);
+                return pickCount;
+            }
+        };
+    }
+}
diff --git a/src/com/android/documentsui/picker/PickFragment.java b/src/com/android/documentsui/picker/PickFragment.java
index 065500d..3ac5974 100644
--- a/src/com/android/documentsui/picker/PickFragment.java
+++ b/src/com/android/documentsui/picker/PickFragment.java
@@ -23,17 +23,19 @@
 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
 import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
 
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
 
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
 import com.android.documentsui.BaseActivity;
 import com.android.documentsui.Injector;
 import com.android.documentsui.R;
@@ -54,15 +56,16 @@
     private final View.OnClickListener mPickListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
-            mInjector.actions.pickDocument(mPickTarget);
+            mInjector.actions.pickDocument(getChildFragmentManager(), mPickTarget);
         }
     };
 
     private final View.OnClickListener mCancelListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
+            mInjector.pickResult.increaseActionCount();
             final BaseActivity activity = BaseActivity.get(PickFragment.this);
-            activity.setResult(Activity.RESULT_CANCELED);
+            activity.setResult(FragmentActivity.RESULT_CANCELED);
             activity.finish();
         }
     };
@@ -98,10 +101,10 @@
             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         mContainer = inflater.inflate(R.layout.fragment_pick, container, false);
 
-        mPick = (TextView) mContainer.findViewById(android.R.id.button1);
+        mPick = (Button) mContainer.findViewById(android.R.id.button1);
         mPick.setOnClickListener(mPickListener);
 
-        mCancel = (TextView) mContainer.findViewById(android.R.id.button2);
+        mCancel = (Button) mContainer.findViewById(android.R.id.button2);
         mCancel.setOnClickListener(mCancelListener);
 
         updateView();
@@ -150,9 +153,24 @@
      * Applies the state of fragment to the view components.
      */
     private void updateView() {
+        if (mPickTarget != null && (
+                mAction == State.ACTION_OPEN_TREE ||
+                        mPickTarget.isCreateSupported())) {
+            mContainer.setVisibility(View.VISIBLE);
+        } else {
+            mContainer.setVisibility(View.GONE);
+            return;
+        }
+
         switch (mAction) {
             case State.ACTION_OPEN_TREE:
-                mPick.setText(R.string.button_select);
+                final BaseActivity activity = (BaseActivity) getActivity();
+                final String target = activity.getCurrentTitle();
+                final String text = TextUtils.isEmpty(target)
+                        ? getString(R.string.button_select)
+                        : getString(R.string.open_tree_button, target);
+                mPick.setText(text);
+                mPick.setWidth(Integer.MAX_VALUE);
                 mCancel.setVisibility(View.GONE);
                 break;
             case State.ACTION_PICK_COPY_DESTINATION:
@@ -180,13 +198,5 @@
                 mContainer.setVisibility(View.GONE);
                 return;
         }
-
-        if (mPickTarget != null && (
-                mAction == State.ACTION_OPEN_TREE ||
-                mPickTarget.isCreateSupported())) {
-            mContainer.setVisibility(View.VISIBLE);
-        } else {
-            mContainer.setVisibility(View.GONE);
-        }
     }
 }
diff --git a/src/com/android/documentsui/picker/PickResult.java b/src/com/android/documentsui/picker/PickResult.java
new file mode 100644
index 0000000..af61a08
--- /dev/null
+++ b/src/com/android/documentsui/picker/PickResult.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2019 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.documentsui.picker;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.documentsui.MetricConsts;
+
+public class PickResult implements android.os.Parcelable {
+    private int mActionCount;
+    private long mDuration;
+    private int mFileCount;
+    private boolean mIsSearching;
+    private @MetricConsts.Root int mRoot;
+    private @MetricConsts.Mime int mMimeType;
+    private int mRepeatedPickTimes;
+
+    // only used for single-select case to get the mRepeatedPickTimes and mMimeType
+    private Uri mFileUri;
+    private long mPickStartTime;
+
+    /**
+     * get total action count during picking.
+     *
+     * @return action count
+     */
+    public int getActionCount() {
+        return mActionCount;
+    }
+
+    /**
+     * increase action count.
+     */
+    public void increaseActionCount() {
+        mActionCount++;
+    }
+
+    /**
+     * get pick duration
+     *
+     * @return pick duration
+     */
+    public long getDuration() {
+        return mDuration;
+    }
+
+    /**
+     * increase pick duration.
+     *
+     * @param currentMillis current time millis
+     */
+    public void increaseDuration(long currentMillis) {
+        mDuration += currentMillis - mPickStartTime;
+        setPickStartTime(currentMillis);
+    }
+
+    /**
+     * set the pick start time.
+     *
+     * @param millis
+     */
+    public void setPickStartTime(long millis) {
+        mPickStartTime = millis;
+    }
+
+    /**
+     * get number of files picked.
+     *
+     * @return file count
+     */
+    public int getFileCount() {
+        return mFileCount;
+    }
+
+    /**
+     * set number of files picked.
+     *
+     * @param count
+     */
+    public void setFileCount(int count) {
+        mFileCount = count;
+    }
+
+    /**
+     * check whether this pick is under searching.
+     *
+     * @return under searching or not
+     */
+    public boolean isSearching() {
+        return mIsSearching;
+    }
+
+    /**
+     * set whether this pick is under searching.
+     *
+     * @param isSearching
+     */
+    public void setIsSearching(boolean isSearching) {
+        this.mIsSearching = isSearching;
+    }
+
+    /**
+     * get the root where the file is picked.
+     *
+     * @return root
+     */
+    public int getRoot() {
+        return mRoot;
+    }
+
+    /**
+     * set the root where the file is picked.
+     *
+     * @param root
+     */
+    public void setRoot(@MetricConsts.Root int root) {
+        this.mRoot = root;
+    }
+
+    /**
+     * get the mime type of the pick file.
+     *
+     * @return mime type
+     */
+    public int getMimeType() {
+        return mMimeType;
+    }
+
+    /**
+     * set the mime type of the pick file.
+     *
+     * @param mimeType
+     */
+    public void setMimeType(@MetricConsts.Mime int mimeType) {
+        this.mMimeType = mimeType;
+    }
+
+    /**
+     * get number of time the selected file is picked repeatedly.
+     *
+     * @return repeatedly pick count
+     */
+    public int getRepeatedPickTimes() {
+        return mRepeatedPickTimes;
+    }
+
+    /**
+     * set number of time the selected file is picked repeatedly.
+     *
+     * @param times the repeatedly pick times
+     */
+    public void setRepeatedPickTimes(int times) {
+        mRepeatedPickTimes = times;
+    }
+
+    /**
+     * get the uri of the selected doc.
+     *
+     * @return file uri
+     */
+    public Uri getFileUri() {
+        return mFileUri;
+    }
+
+    /**
+     * set the uri of the selected doc.
+     *
+     * @param fileUri the selected doc uri
+     */
+    public void setFileUri(Uri fileUri) {
+        this.mFileUri = fileUri;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mActionCount);
+        out.writeLong(mDuration);
+        out.writeInt(mFileCount);
+        out.writeInt(mIsSearching ? 1 : 0);
+        out.writeInt(mRoot);
+        out.writeInt(mMimeType);
+        out.writeInt(mRepeatedPickTimes);
+    }
+
+    public static final Parcelable.ClassLoaderCreator<PickResult>
+            CREATOR = new Parcelable.ClassLoaderCreator<PickResult>() {
+        @Override
+        public PickResult createFromParcel(Parcel in) {
+            return createFromParcel(in, null);
+        }
+
+        @Override
+        public PickResult createFromParcel(Parcel in, ClassLoader loader) {
+            final PickResult result = new PickResult();
+            result.mActionCount = in.readInt();
+            result.mDuration = in.readLong();
+            result.mFileCount = in.readInt();
+            result.mIsSearching = in.readInt() != 0;
+            result.mRoot = in.readInt();
+            result.mMimeType = in.readInt();
+            result.mRepeatedPickTimes = in.readInt();
+            return result;
+        }
+
+        @Override
+        public PickResult[] newArray(int size) {
+            return new PickResult[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return "PickResults{" +
+                "actionCount=" + mActionCount +
+                ", mDuration=" + mDuration +
+                ", mFileCount=" + mFileCount +
+                ", mIsSearching=" + mIsSearching +
+                ", mRoot=" + mRoot +
+                ", mMimeType=" + mMimeType +
+                ", mRepeatedPickTimes=" + mRepeatedPickTimes +
+                '}';
+    }
+}
diff --git a/src/com/android/documentsui/picker/SaveFragment.java b/src/com/android/documentsui/picker/SaveFragment.java
index f9d74e9..f881768 100644
--- a/src/com/android/documentsui/picker/SaveFragment.java
+++ b/src/com/android/documentsui/picker/SaveFragment.java
@@ -16,9 +16,6 @@
 
 package com.android.documentsui.picker;
 
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
 import android.content.Context;
 import android.os.Bundle;
 import android.text.Editable;
@@ -34,6 +31,10 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
 import com.android.documentsui.IconUtils;
 import com.android.documentsui.Injector;
 import com.android.documentsui.R;
@@ -117,7 +118,7 @@
                     }
                 });
 
-        mSave = (TextView) view.findViewById(android.R.id.button1);
+        mSave = (Button) view.findViewById(android.R.id.button1);
         mSave.setOnClickListener(mSaveListener);
         mSave.setEnabled(false);
 
diff --git a/src/com/android/documentsui/picker/UpdatePickResultTask.java b/src/com/android/documentsui/picker/UpdatePickResultTask.java
new file mode 100644
index 0000000..ff35137
--- /dev/null
+++ b/src/com/android/documentsui/picker/UpdatePickResultTask.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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.documentsui.picker;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.SystemClock;
+import com.android.documentsui.Metrics;
+
+// load & update mime type & repeatedly pick count in background
+public class UpdatePickResultTask extends AsyncTask<Void, Void, Void> {
+    private Context mContext;
+    private PickResult mPickResult;
+    private PickCountRecordStorage mPickCountRecord;
+
+    public UpdatePickResultTask(Context context, PickResult pickResult) {
+        this(context, pickResult, PickCountRecordStorage.create());
+    }
+
+    public UpdatePickResultTask(Context context, PickResult pickResult,
+        PickCountRecordStorage pickCountRecord) {
+        mContext = context.getApplicationContext();
+        mPickResult = pickResult;
+        mPickCountRecord = pickCountRecord;
+    }
+
+    @Override
+    protected void onPreExecute() {
+        mPickResult.increaseDuration(SystemClock.uptimeMillis());
+    }
+
+    @Override
+    protected Void doInBackground(Void... voids) {
+        Uri fileUri = mPickResult.getFileUri();
+        if (fileUri != null) {
+            mPickResult.setMimeType(
+                Metrics.sanitizeMime(mContext.getContentResolver().getType(fileUri)));
+
+            mPickResult.setRepeatedPickTimes(
+                mPickCountRecord.increasePickCountRecord(mContext, fileUri));
+        }
+        return null;
+    }
+
+    @Override
+    protected void onPostExecute(Void aVoid) {
+        Metrics.logPickResult(mPickResult);
+    }
+
+}
diff --git a/src/com/android/documentsui/prefs/BackupAgent.java b/src/com/android/documentsui/prefs/BackupAgent.java
index 65a94ca..d742dc5 100644
--- a/src/com/android/documentsui/prefs/BackupAgent.java
+++ b/src/com/android/documentsui/prefs/BackupAgent.java
@@ -22,7 +22,7 @@
 import android.app.backup.SharedPreferencesBackupHelper;
 import android.content.SharedPreferences;
 import android.os.ParcelFileDescriptor;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 
 import java.io.IOException;
 
diff --git a/src/com/android/documentsui/prefs/LocalPreferences.java b/src/com/android/documentsui/prefs/LocalPreferences.java
index 955b19d..252ec1f 100644
--- a/src/com/android/documentsui/prefs/LocalPreferences.java
+++ b/src/com/android/documentsui/prefs/LocalPreferences.java
@@ -18,7 +18,7 @@
 
 import static com.android.documentsui.base.State.MODE_UNKNOWN;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
diff --git a/src/com/android/documentsui/prefs/PrefsBackupHelper.java b/src/com/android/documentsui/prefs/PrefsBackupHelper.java
index 93043f8..01b36bd 100644
--- a/src/com/android/documentsui/prefs/PrefsBackupHelper.java
+++ b/src/com/android/documentsui/prefs/PrefsBackupHelper.java
@@ -19,7 +19,7 @@
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.preference.PreferenceManager;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 
 import java.util.Map;
 
diff --git a/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java b/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
index 5da0e49..0bdd484 100644
--- a/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
+++ b/src/com/android/documentsui/prefs/ScopedAccessLocalPreferences.java
@@ -15,34 +15,16 @@
  */
 package com.android.documentsui.prefs;
 
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-import static com.android.documentsui.base.SharedMinimal.DIRECTORY_ROOT;
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
-import android.os.UserHandle;
 import android.preference.PreferenceManager;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * Methods for accessing the local preferences with regards to scoped directory access.
+ * TODO(b/111892460): Delete this class after Q is released.
  */
-//TODO(b/72055774): add unit tests
+@Deprecated
 public class ScopedAccessLocalPreferences {
 
     private static final String TAG = "ScopedAccessLocalPreferences";
@@ -51,188 +33,21 @@
         return PreferenceManager.getDefaultSharedPreferences(context);
     }
 
-    public static final int PERMISSION_ASK = 0;
-    public static final int PERMISSION_ASK_AGAIN = 1;
-    public static final int PERMISSION_NEVER_ASK = -1;
-    // NOTE: this status is not used on preferences, but on permissions granted by AM
-    public static final int PERMISSION_GRANTED = 2;
-
-    @IntDef(flag = true, value = {
-            PERMISSION_ASK,
-            PERMISSION_ASK_AGAIN,
-            PERMISSION_NEVER_ASK,
-            PERMISSION_GRANTED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PermissionStatus {}
-
-    private static final String KEY_REGEX = "^.+\\|(.+)\\|(.*)\\|(.+)$";
-    private static final Pattern KEY_PATTERN = Pattern.compile(KEY_REGEX);
-
-    /**
-     * Methods below are used to keep track of denied user requests on scoped directory access so
-     * the dialog is not offered when user checked the 'Do not ask again' box
-     *
-     * <p>It uses a shared preferences, whose key is:
-     * <ol>
-     * <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID
-     * (typically physical volumes like SD cards).
-     * <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID
-     * (typically the emulated volume used for primary storage
-     * </ol>
-     */
-    public static @PermissionStatus int getScopedAccessPermissionStatus(Context context,
-            String packageName, @Nullable String uuid, String directory) {
-        final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
-        return getPrefs(context).getInt(key, PERMISSION_ASK);
-    }
-
-    public static void setScopedAccessPermissionStatus(Context context, String packageName,
-            @Nullable String uuid, String directory, @PermissionStatus int status) {
-        checkArgument(!TextUtils.isEmpty(directory),
-                "Cannot pass empty directory - did you mean %s?", DIRECTORY_ROOT);
-        final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
-        if (DEBUG) {
-            Log.d(TAG, "Setting permission of " + packageName + ":" + uuid + ":" + directory
-                    + " to " + statusAsString(status));
-        }
-
-        getPrefs(context).edit().putInt(key, status).apply();
-    }
-
-    public static int clearScopedAccessPreferences(Context context, String packageName) {
-        final String keySubstring = "|" + packageName + "|";
+    /** Clears all scoped directory access preferences. */
+    public static void clearScopedAccessPreferences(Context context) {
+        final String keySubstring = "|";
         final SharedPreferences prefs = getPrefs(context);
         Editor editor = null;
-        int removed = 0;
         for (final String key : prefs.getAll().keySet()) {
             if (key.contains(keySubstring)) {
                 if (editor == null) {
                     editor = prefs.edit();
                 }
                 editor.remove(key);
-                removed ++;
             }
         }
         if (editor != null) {
             editor.apply();
         }
-        return removed;
-    }
-
-    private static String getScopedAccessDenialsKey(String packageName, @Nullable String uuid,
-            String directory) {
-        final int userId = UserHandle.myUserId();
-        return uuid == null
-                ? userId + "|" + packageName + "||" + directory
-                : userId + "|" + packageName + "|" + uuid + "|" + directory;
-    }
-
-    /**
-     * Clears all preferences associated with a given package.
-     *
-     * <p>Typically called when a package is removed or when user asked to clear its data.
-     */
-    public static void clearPackagePreferences(Context context, String packageName) {
-        ScopedAccessLocalPreferences.clearScopedAccessPreferences(context, packageName);
-    }
-
-    /**
-     * Gets all packages that have entries in the preferences
-     */
-    public static Set<String> getAllPackages(Context context) {
-        final SharedPreferences prefs = getPrefs(context);
-
-        final ArraySet<String> pkgs = new ArraySet<>();
-        for (Entry<String, ?> pref : prefs.getAll().entrySet()) {
-            final String key = pref.getKey();
-            final String pkg = getPackage(key);
-            if (pkg == null) {
-                Log.w(TAG, "getAllPackages(): error parsing pref '" + key + "'");
-                continue;
-            }
-            pkgs.add(pkg);
-        }
-        return pkgs;
-    }
-
-    /**
-     * Gets all permissions.
-     */
-    public static List<Permission> getAllPermissions(Context context) {
-        final SharedPreferences prefs = getPrefs(context);
-        final ArrayList<Permission> permissions = new ArrayList<>();
-
-        for (Entry<String, ?> pref : prefs.getAll().entrySet()) {
-            final String key = pref.getKey();
-            final Object value = pref.getValue();
-            final Integer status;
-            try {
-                status = (Integer) value;
-            } catch (Exception e) {
-                Log.w(TAG, "error gettting value for key '" + key + "': " + value);
-                continue;
-            }
-            final Permission permission = getPermission(key, status);
-            if (permission != null) {
-                permissions.add(permission);
-            }
-        }
-
-        return permissions;
-    }
-
-    public static String statusAsString(@PermissionStatus int status) {
-        switch (status) {
-            case PERMISSION_ASK:
-                return "PERMISSION_ASK";
-            case PERMISSION_ASK_AGAIN:
-                return "PERMISSION_ASK_AGAIN";
-            case PERMISSION_NEVER_ASK:
-                return "PERMISSION_NEVER_ASK";
-            case PERMISSION_GRANTED:
-                return "PERMISSION_GRANTED";
-            default:
-                return "UNKNOWN";
-        }
-    }
-
-    @Nullable
-    private static String getPackage(String key) {
-        final Matcher matcher = KEY_PATTERN.matcher(key);
-        return matcher.matches() ? matcher.group(1) : null;
-    }
-
-    private static Permission getPermission(String key, Integer status) {
-        final Matcher matcher = KEY_PATTERN.matcher(key);
-        if (!matcher.matches()) return null;
-
-        final String pkg = matcher.group(1);
-        final String uuid = matcher.group(2);
-        final String directory = matcher.group(3);
-
-        return new Permission(pkg, uuid, directory, status);
-    }
-
-    public static final class Permission {
-        public final String pkg;
-
-        @Nullable
-        public final String uuid;
-        public final String directory;
-        public final int status;
-
-        public Permission(String pkg, String uuid, String directory, Integer status) {
-            this.pkg = pkg;
-            this.uuid = TextUtils.isEmpty(uuid) ? null : uuid;
-            this.directory = directory;
-            this.status = status.intValue();
-        }
-
-        @Override
-        public String toString() {
-            return "Permission: [pkg=" + pkg + ", uuid=" + uuid + ", dir=" + directory + ", status="
-                    + statusAsString(status) + " (" + status + ")]";
-        }
     }
 }
diff --git a/src/com/android/documentsui/queries/CommandInterceptor.java b/src/com/android/documentsui/queries/CommandInterceptor.java
index 143b933..4119f14 100644
--- a/src/com/android/documentsui/queries/CommandInterceptor.java
+++ b/src/com/android/documentsui/queries/CommandInterceptor.java
@@ -18,7 +18,7 @@
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
 import android.content.Context;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -48,8 +48,6 @@
         mCommands.add(this::quickViewer);
         mCommands.add(this::gestureScale);
         mCommands.add(this::jobProgressDialog);
-        mCommands.add(this::archiveCreation);
-        mCommands.add(this::docInspector);
         mCommands.add(this::docDetails);
         mCommands.add(this::forcePaging);
     }
@@ -65,7 +63,9 @@
         }
 
         if (!mFeatures.isCommandInterceptorEnabled()) {
-            if (DEBUG) Log.v(TAG, "Skipping input, command interceptor disabled.");
+            if (DEBUG) {
+                Log.v(TAG, "Skipping input, command interceptor disabled.");
+            }
             return false;
         }
 
@@ -124,32 +124,8 @@
         return false;
     }
 
-    private boolean archiveCreation(String[] tokens) {
-        if ("zip".equals(tokens[0])) {
-            if (tokens.length == 2 && !TextUtils.isEmpty(tokens[1])) {
-                boolean enabled = asBool(tokens[1]);
-                mFeatures.forceFeature(R.bool.feature_archive_creation, enabled);
-                Log.i(TAG, "Set gesture scale enabled to: " + enabled);
-                return true;
-            }
-            Log.w(TAG, "Invalid command structure: " + TextUtils.join(" ", tokens));
-        }
-        return false;
-    }
-
-    private boolean docInspector(String[] tokens) {
-        if ("inspect".equals(tokens[0])) {
-            if (tokens.length == 2 && !TextUtils.isEmpty(tokens[1])) {
-                boolean enabled = asBool(tokens[1]);
-                mFeatures.forceFeature(R.bool.feature_inspector, enabled);
-                Log.i(TAG, "Set doc inspector enabled to: " + enabled);
-                return true;
-            }
-            Log.w(TAG, "Invalid command structure: " + TextUtils.join(" ", tokens));
-        }
-        return false;
-    }
-
+    // Include document debug info in Get Info panel.
+    // enabled by default on DEBUG builds.
     private boolean docDetails(String[] tokens) {
         if ("docinfo".equals(tokens[0])) {
             if (tokens.length == 2 && !TextUtils.isEmpty(tokens[1])) {
diff --git a/src/com/android/documentsui/queries/SearchChipData.java b/src/com/android/documentsui/queries/SearchChipData.java
new file mode 100644
index 0000000..1ce9b74
--- /dev/null
+++ b/src/com/android/documentsui/queries/SearchChipData.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.documentsui.queries;
+
+/**
+ * A data class stored data which search chip row required.
+ * Used by {@link SearchChipViewManager}.
+ */
+public class SearchChipData {
+
+    private final int mChipType;
+    private final int mTitleRes;
+    private final String[] mMimeTypes;
+
+    public SearchChipData(int chipType, int titleRes, String[] mimeTypes) {
+        mChipType = chipType;
+        mTitleRes = titleRes;
+        mMimeTypes = mimeTypes;
+    }
+
+    public final int getTitleRes() {
+        return mTitleRes;
+    }
+
+    public final String[] getMimeTypes() {
+        return mMimeTypes;
+    }
+
+    public final int getChipType() {
+        return mChipType;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/queries/SearchChipViewManager.java b/src/com/android/documentsui/queries/SearchChipViewManager.java
new file mode 100644
index 0000000..959da31
--- /dev/null
+++ b/src/com/android/documentsui/queries/SearchChipViewManager.java
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2018 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.documentsui.queries;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.HorizontalScrollView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.documentsui.IconUtils;
+import com.android.documentsui.MetricConsts;
+import com.android.documentsui.R;
+import com.android.documentsui.base.MimeTypes;
+import com.android.documentsui.base.Shared;
+
+import com.google.android.material.chip.Chip;
+import com.google.common.primitives.Ints;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Manages search chip behavior.
+ */
+public class SearchChipViewManager {
+
+    private static final int CHIP_MOVE_ANIMATION_DURATION = 250;
+
+    private static final int TYPE_IMAGES = MetricConsts.TYPE_CHIP_IMAGES;;
+    private static final int TYPE_DOCUMENTS = MetricConsts.TYPE_CHIP_DOCS;
+    private static final int TYPE_AUDIO = MetricConsts.TYPE_CHIP_AUDIOS;
+    private static final int TYPE_VIDEOS = MetricConsts.TYPE_CHIP_VIDEOS;
+
+    private static final ChipComparator CHIP_COMPARATOR = new ChipComparator();
+
+    // we will get the icon drawable with the first mimeType
+    private static final String[] IMAGES_MIMETYPES = new String[]{"image/*"};
+    private static final String[] VIDEOS_MIMETYPES = new String[]{"video/*"};
+    private static final String[] AUDIO_MIMETYPES =
+            new String[]{"audio/*", "application/ogg", "application/x-flac"};
+    private static final String[] DOCUMENTS_MIMETYPES = new String[]{"application/*", "text/*"};
+
+    private static final Map<Integer, SearchChipData> sChipItems = new HashMap<>();
+
+    private final ViewGroup mChipGroup;
+    private final List<Integer> mDefaultChipTypes = new ArrayList<>();
+    private SearchChipViewManagerListener mListener;
+    private String[] mCurrentUpdateMimeTypes;
+    private boolean mIsFirstUpdateChipsReady;
+
+    @VisibleForTesting
+    Set<SearchChipData> mCheckedChipItems = new HashSet<>();
+
+    static {
+        sChipItems.put(TYPE_IMAGES,
+                new SearchChipData(TYPE_IMAGES, R.string.chip_title_images, IMAGES_MIMETYPES));
+        sChipItems.put(TYPE_DOCUMENTS,
+                new SearchChipData(TYPE_DOCUMENTS, R.string.chip_title_documents,
+                        DOCUMENTS_MIMETYPES));
+        sChipItems.put(TYPE_AUDIO,
+                new SearchChipData(TYPE_AUDIO, R.string.chip_title_audio, AUDIO_MIMETYPES));
+        sChipItems.put(TYPE_VIDEOS,
+                new SearchChipData(TYPE_VIDEOS, R.string.chip_title_videos, VIDEOS_MIMETYPES));
+    }
+
+    public SearchChipViewManager(@NonNull ViewGroup chipGroup) {
+        mChipGroup = chipGroup;
+    }
+
+    /**
+     * Restore the checked chip items by the saved state.
+     *
+     * @param savedState the saved state to restore.
+     */
+    public void restoreCheckedChipItems(Bundle savedState) {
+        final int[] chipTypes = savedState.getIntArray(Shared.EXTRA_QUERY_CHIPS);
+        if (chipTypes != null) {
+            clearCheckedChips();
+            for (int chipType : chipTypes) {
+                final SearchChipData chipData = sChipItems.get(chipType);
+                mCheckedChipItems.add(chipData);
+                setCheckedChip(chipData.getChipType());
+            }
+        }
+    }
+
+    /**
+     * Set the visibility of the chips row. If the count of chips is less than 2,
+     * we will hide the chips row.
+     *
+     * @param show the value to show/hide the chips row.
+     */
+    public void setChipsRowVisible(boolean show) {
+        // if there is only one matched chip, hide the chip group.
+        mChipGroup.setVisibility(show && mChipGroup.getChildCount() > 1 ? View.VISIBLE : View.GONE);
+    }
+
+    /**
+     * Check Whether the checked item list has contents.
+     *
+     * @return True, if the checked item list is not empty. Otherwise, return false.
+     */
+    public boolean hasCheckedItems() {
+        return !mCheckedChipItems.isEmpty();
+    }
+
+    /**
+     * Clear the checked state of Chips and the checked list.
+     */
+    public void clearCheckedChips() {
+        final int count = mChipGroup.getChildCount();
+        for (int i = 0; i < count; i++) {
+            Chip child = (Chip) mChipGroup.getChildAt(i);
+            setChipChecked(child, false /* isChecked */);
+        }
+        mCheckedChipItems.clear();
+    }
+
+    /**
+     * Get the mime types of checked chips
+     *
+     * @return the string array of mime types
+     */
+    public String[] getCheckedMimeTypes() {
+        final ArrayList<String> args = new ArrayList<>();
+        for (SearchChipData data : mCheckedChipItems) {
+            for (String mimeType : data.getMimeTypes()) {
+                args.add(mimeType);
+            }
+        }
+        return args.toArray(new String[0]);
+    }
+
+    /**
+     * Called when owning activity is saving state to be used to restore state during creation.
+     *
+     * @param state Bundle to save state
+     */
+    public void onSaveInstanceState(Bundle state) {
+        List<Integer> checkedChipList = new ArrayList<>();
+
+        for (SearchChipData item : mCheckedChipItems) {
+            checkedChipList.add(item.getChipType());
+        }
+
+        if (checkedChipList.size() > 0) {
+            state.putIntArray(Shared.EXTRA_QUERY_CHIPS, Ints.toArray(checkedChipList));
+        }
+    }
+
+    /**
+     * Initialize the search chips base on the mime types.
+     *
+     * @param acceptMimeTypes use this values to filter chips
+     */
+    public void initChipSets(String[] acceptMimeTypes) {
+        mDefaultChipTypes.clear();
+        for (SearchChipData chipData : sChipItems.values()) {
+            final String[] mimeTypes = chipData.getMimeTypes();
+            final boolean isMatched = MimeTypes.mimeMatches(acceptMimeTypes, mimeTypes);
+            if (isMatched) {
+                mDefaultChipTypes.add(chipData.getChipType());
+            }
+        }
+    }
+
+    /**
+     * Update the search chips base on the mime types.
+     *
+     * @param acceptMimeTypes use this values to filter chips
+     */
+    public void updateChips(String[] acceptMimeTypes) {
+        if (mIsFirstUpdateChipsReady && Arrays.equals(mCurrentUpdateMimeTypes, acceptMimeTypes)) {
+            return;
+        }
+
+        final Context context = mChipGroup.getContext();
+        mChipGroup.removeAllViews();
+
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        for (Integer chipType : mDefaultChipTypes) {
+            final SearchChipData chipData = sChipItems.get(chipType);
+            final String[] mimeTypes = chipData.getMimeTypes();
+            final boolean isMatched = MimeTypes.mimeMatches(acceptMimeTypes, mimeTypes);
+            if (isMatched) {
+                addChipToGroup(mChipGroup, chipData, inflater);
+            }
+        }
+        reorderCheckedChips(null /* clickedChip */, false /* hasAnim */);
+        mIsFirstUpdateChipsReady = true;
+        mCurrentUpdateMimeTypes = acceptMimeTypes;
+        if (mChipGroup.getChildCount() < 2) {
+            mChipGroup.setVisibility(View.GONE);
+        }
+    }
+
+    private void addChipToGroup(ViewGroup group, SearchChipData data, LayoutInflater inflater) {
+        Chip chip = (Chip) inflater.inflate(R.layout.search_chip_item, mChipGroup, false);
+        bindChip(chip, data);
+        group.addView(chip);
+    }
+
+    /**
+     * Mirror chip group here for another chip group
+     *
+     * @param chipGroup target view group for mirror
+     */
+    public void bindMirrorGroup(ViewGroup chipGroup) {
+        final int size = mChipGroup.getChildCount();
+        if (size <= 1) {
+            chipGroup.setVisibility(View.GONE);
+            return;
+        }
+
+        chipGroup.setVisibility(View.VISIBLE);
+        chipGroup.removeAllViews();
+        final LayoutInflater inflater = LayoutInflater.from(chipGroup.getContext());
+        for (int i = 0; i < size; i++) {
+            Chip child = (Chip) mChipGroup.getChildAt(i);
+            SearchChipData item = (SearchChipData) child.getTag();
+            addChipToGroup(chipGroup, item, inflater);
+        }
+    }
+
+    /**
+     * Click behavior handle here when mirror chip clicked.
+     *
+     * @param data SearchChipData synced in mirror group
+     */
+    public void onMirrorChipClick(SearchChipData data) {
+        for (int i = 0, size = mChipGroup.getChildCount(); i < size; i++) {
+            Chip chip = (Chip) mChipGroup.getChildAt(i);
+            if (chip.getTag().equals(data)) {
+                chip.setChecked(!chip.isChecked());
+                onChipClick(chip);
+                return;
+            }
+        }
+    }
+
+    /**
+     * Set the listener.
+     *
+     * @param listener the listener
+     */
+    public void setSearchChipViewManagerListener(SearchChipViewManagerListener listener) {
+        mListener = listener;
+    }
+
+    private static void setChipChecked(Chip chip, boolean isChecked) {
+        chip.setChecked(isChecked);
+        chip.setChipIconVisible(!isChecked);
+    }
+
+    private void setCheckedChip(int chipType) {
+        final int count = mChipGroup.getChildCount();
+        for (int i = 0; i < count; i++) {
+            Chip child = (Chip) mChipGroup.getChildAt(i);
+            SearchChipData item = (SearchChipData) child.getTag();
+            if (item.getChipType() == chipType) {
+                setChipChecked(child, true /* isChecked */);
+                break;
+            }
+        }
+    }
+
+    private void onChipClick(View v) {
+        final Chip chip = (Chip) v;
+
+        // We need to show/hide the chip icon in our design.
+        // When we show/hide the chip icon or do reorder animation,
+        // the ripple effect will be interrupted. So, skip ripple
+        // effect when the chip is clicked.
+        chip.getBackground().setVisible(false /* visible */, false /* restart */);
+
+        final SearchChipData item = (SearchChipData) chip.getTag();
+        if (chip.isChecked()) {
+            mCheckedChipItems.add(item);
+        } else {
+            mCheckedChipItems.remove(item);
+        }
+
+        setChipChecked(chip, chip.isChecked());
+        reorderCheckedChips(chip, true /* hasAnim */);
+
+        if (mListener != null) {
+            mListener.onChipCheckStateChanged(v);
+        }
+    }
+
+    private void bindChip(Chip chip, SearchChipData chipData) {
+        chip.setTag(chipData);
+        chip.setText(mChipGroup.getContext().getString(chipData.getTitleRes()));
+        // get the icon drawable with the first mimeType
+        chip.setChipIcon(
+                IconUtils.loadMimeIcon(mChipGroup.getContext(), chipData.getMimeTypes()[0]));
+        chip.setOnClickListener(this::onChipClick);
+
+        if (mCheckedChipItems.contains(chipData)) {
+            setChipChecked(chip, true);
+        }
+    }
+
+    /**
+     * Reorder the chips in chip group. The checked chip has higher order.
+     *
+     * @param clickedChip the clicked chip, may be null.
+     * @param hasAnim if true, play move animation. Otherwise, not.
+     */
+    private void reorderCheckedChips(@Nullable Chip clickedChip, boolean hasAnim) {
+        final ArrayList<Chip> chipList = new ArrayList<>();
+        final int count = mChipGroup.getChildCount();
+
+        // if the size of chips is less than 2, no need to reorder chips
+        if (count < 2) {
+            return;
+        }
+
+        Chip item;
+        // get the default order
+        for (int i = 0; i < count; i++) {
+            item = (Chip) mChipGroup.getChildAt(i);
+            chipList.add(item);
+        }
+
+        // sort chips
+        Collections.sort(chipList, CHIP_COMPARATOR);
+
+        if (isChipOrderMatched(mChipGroup, chipList)) {
+            // the order of chips is not changed
+            return;
+        }
+
+        final int chipSpacing = mChipGroup.getPaddingEnd();
+        final boolean isRtl = mChipGroup.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        float lastX = isRtl ? mChipGroup.getWidth() - chipSpacing : chipSpacing;
+
+        // remove all chips except current clicked chip to avoid losing
+        // accessibility focus.
+        for (int i = count - 1; i >= 0; i--) {
+            item = (Chip) mChipGroup.getChildAt(i);
+            if (!item.equals(clickedChip)) {
+                mChipGroup.removeView(item);
+            }
+        }
+
+        // add sorted chips
+        for (int i = 0; i < count; i++) {
+            item = chipList.get(i);
+            if (!item.equals(clickedChip)) {
+                mChipGroup.addView(item, i);
+            }
+        }
+
+        if (hasAnim && mChipGroup.isAttachedToWindow()) {
+            // start animation
+            for (Chip chip : chipList) {
+                if (isRtl) {
+                    lastX -= chip.getMeasuredWidth();
+                }
+
+                ObjectAnimator animator = ObjectAnimator.ofFloat(chip, "x", chip.getX(), lastX);
+
+                if (isRtl) {
+                    lastX -= chipSpacing;
+                } else {
+                    lastX += chip.getMeasuredWidth() + chipSpacing;
+                }
+                animator.setDuration(CHIP_MOVE_ANIMATION_DURATION);
+                animator.start();
+            }
+
+            // Let the first checked chip can be shown.
+            View parent = (View) mChipGroup.getParent();
+            if (parent instanceof HorizontalScrollView) {
+                final int scrollToX = isRtl ? parent.getWidth() : 0;
+                ((HorizontalScrollView) parent).smoothScrollTo(scrollToX, 0);
+            }
+        }
+    }
+
+    private static boolean isChipOrderMatched(ViewGroup chipGroup, ArrayList<Chip> chipList) {
+        if (chipGroup == null || chipList == null) {
+            return false;
+        }
+
+        final int chipCount = chipList.size();
+        if (chipGroup.getChildCount() != chipCount) {
+            return false;
+        }
+        for (int i = 0; i < chipCount; i++) {
+            if (!chipList.get(i).equals(chipGroup.getChildAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * The listener of SearchChipViewManager.
+     */
+    public interface SearchChipViewManagerListener {
+        /**
+         * It will be triggered when the checked state of chips changes.
+         */
+        void onChipCheckStateChanged(View v);
+    }
+
+    private static class ChipComparator implements Comparator<Chip> {
+
+        @Override
+        public int compare(Chip lhs, Chip rhs) {
+            return (lhs.isChecked() == rhs.isChecked()) ? 0 : (lhs.isChecked() ? -1 : 1);
+        }
+    }
+}
diff --git a/src/com/android/documentsui/queries/SearchFragment.java b/src/com/android/documentsui/queries/SearchFragment.java
new file mode 100644
index 0000000..5eb7435
--- /dev/null
+++ b/src/com/android/documentsui/queries/SearchFragment.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2019 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.documentsui.queries;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.SearchView;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.Injector;
+import com.android.documentsui.R;
+
+import java.util.List;
+
+public class SearchFragment extends DialogFragment
+        implements SearchView.OnQueryTextListener{
+
+    private static final String TAG = "SearchFragment";
+    private static final String KEY_QUERY = "query";
+    private static final int MAX_DISPLAY_ITEMS = 8;
+
+    private SearchViewManager mSearchViewManager;
+
+    private SearchView mSearchView;
+    private ViewGroup mSearchChipGroup;
+    private ListView mListView;
+    private ArrayAdapter<String> mAdapter;
+
+    private List<String> mHistoryList;
+
+    public static void showFragment(FragmentManager fm, String initQuery) {
+        final SearchFragment fragment = new SearchFragment();
+        final Bundle args = new Bundle();
+        args.putString(KEY_QUERY, initQuery);
+        fragment.setArguments(args);
+        fragment.setStyle(DialogFragment.STYLE_NO_FRAME, R.style.DocumentsTheme);
+        fragment.show(fm, TAG);
+    }
+
+    public static SearchFragment get(FragmentManager fm) {
+        final Fragment fragment = fm.findFragmentByTag(TAG);
+        return fragment instanceof SearchFragment
+                ? (SearchFragment) fragment
+                : null;
+    }
+
+    private void onChipClicked(View view) {
+        final Object tag = view.getTag();
+        if (tag instanceof SearchChipData) {
+            mSearchViewManager.onMirrorChipClick((SearchChipData) tag);
+            dismiss();
+        }
+    }
+
+    private void onHistoryItemClicked(AdapterView<?> parent, View view, int position, long id) {
+        final String item = mHistoryList.get(position);
+        mSearchViewManager.setHistorySearch();
+        mSearchView.setQuery(item, true);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        final View view = inflater.inflate(R.layout.fragment_search, container, false);
+
+        final Toolbar toolbar = view.findViewById(R.id.toolbar);
+        toolbar.setNavigationOnClickListener(v -> {
+            mSearchViewManager.cancelSearch();
+            dismiss();
+        });
+
+        mSearchView = view.findViewById(R.id.search_view);
+        mSearchChipGroup = view.findViewById(R.id.search_chip_group);
+        mListView = view.findViewById(R.id.history_list);
+
+        return view;
+    }
+
+    @Override
+    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        final BaseActivity activity = (BaseActivity) getActivity();
+        final Injector injector = activity.getInjector();
+        mSearchViewManager = injector.searchManager;
+
+        final String currentQuery = getArguments().getString(KEY_QUERY, "");
+
+        mSearchView.onActionViewExpanded();
+        mSearchView.setQuery(currentQuery, false);
+        mSearchView.setOnQueryTextListener(this);
+        mHistoryList = SearchHistoryManager.getInstance(
+                getContext().getApplicationContext()).getHistoryList(currentQuery);
+
+        mSearchViewManager.bindChips(mSearchChipGroup);
+        if (mSearchChipGroup.getVisibility() == View.VISIBLE) {
+            for (int i = 0, size = mSearchChipGroup.getChildCount(); i < size; i++) {
+                mSearchChipGroup.getChildAt(i).setOnClickListener(this::onChipClicked);
+            }
+        }
+
+        mAdapter = new HistoryListAdapter(getContext(), mHistoryList);
+        mListView.setAdapter(mAdapter);
+        mListView.setOnItemClickListener(this::onHistoryItemClicked);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+    }
+
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        return new Dialog(getActivity(), getTheme()){
+            @Override
+            public void onBackPressed() {
+                if (TextUtils.isEmpty(mSearchView.getQuery())) {
+                    mSearchViewManager.cancelSearch();
+                } else {
+                    mSearchViewManager.restoreSearch(false);
+                }
+                dismiss();
+            }
+        };
+    }
+
+    @Override
+    public boolean onQueryTextSubmit(String s) {
+        if (!TextUtils.isEmpty(mSearchView.getQuery())) {
+            mSearchViewManager.setCurrentSearch(s);
+            mSearchViewManager.restoreSearch(false);
+            mSearchViewManager.recordHistory();
+            dismiss();
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onQueryTextChange(String s) {
+        if (!TextUtils.isEmpty(mSearchView.getQuery())) {
+            mSearchViewManager.setCurrentSearch(s);
+            mSearchViewManager.restoreSearch(true);
+            dismiss();
+        } else {
+            mHistoryList = SearchHistoryManager.getInstance(
+                    mSearchView.getContext().getApplicationContext()).getHistoryList("");
+            mAdapter.clear();
+            mAdapter.addAll(mHistoryList);
+        }
+        return true;
+    }
+
+    private class HistoryListAdapter extends ArrayAdapter<String> {
+
+        public HistoryListAdapter(Context context, List<String> list) {
+            super(context, R.layout.item_history, list);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = getLayoutInflater().inflate(R.layout.item_history, parent, false);
+            }
+            final String history = getItem(position);
+            final TextView text = convertView.findViewById(android.R.id.title);
+            final View button = convertView.findViewById(android.R.id.icon);
+
+            text.setText(history);
+            button.setOnClickListener(v -> {
+                mSearchViewManager.removeHistory(history);
+                mHistoryList.remove(history);
+                notifyDataSetChanged();
+            });
+            button.setContentDescription(
+                    getContext().getString(R.string.delete_search_history, history));
+
+            return convertView;
+        }
+
+        @Override
+        public int getCount() {
+            final int count = super.getCount();
+            return count > MAX_DISPLAY_ITEMS ? MAX_DISPLAY_ITEMS : count;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/queries/SearchHistoryManager.java b/src/com/android/documentsui/queries/SearchHistoryManager.java
new file mode 100644
index 0000000..26def87
--- /dev/null
+++ b/src/com/android/documentsui/queries/SearchHistoryManager.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2019 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.documentsui.queries;
+
+import static com.android.documentsui.base.SharedMinimal.DEBUG;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.os.AsyncTask;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.documentsui.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A manager used to manage search history data.
+ */
+public class SearchHistoryManager {
+
+    private static final String TAG = "SearchHistoryManager";
+
+    private static final String[] PROJECTION_HISTORY = new String[]{
+            DatabaseHelper.COLUMN_KEYWORD, DatabaseHelper.COLUMN_LAST_UPDATED_TIME
+    };
+
+    private static SearchHistoryManager sManager;
+    private final DatabaseHelper mHelper;
+    private final int mLimitedHistoryCount;
+    @GuardedBy("mLock")
+    private final List<String> mHistory = Collections.synchronizedList(new ArrayList<>());
+    private final Object mLock = new Object();
+    private DatabaseChangedListener mListener;
+
+    private enum DATABASE_OPERATION {
+        QUERY, ADD, DELETE, UPDATE
+    }
+
+    private SearchHistoryManager(Context context) {
+        mHelper = new DatabaseHelper(context);
+        mLimitedHistoryCount = context.getResources().getInteger(
+            R.integer.config_maximum_search_history);
+    }
+
+    /**
+     * Get the singleton instance of SearchHistoryManager.
+     *
+     * @return the singleton instance, guaranteed not null
+     */
+    public static SearchHistoryManager getInstance(Context context) {
+        synchronized (SearchHistoryManager.class) {
+            if (sManager == null) {
+                sManager = new SearchHistoryManager(context);
+                sManager.new DatabaseTask(null, DATABASE_OPERATION.QUERY).executeOnExecutor(
+                    AsyncTask.SERIAL_EXECUTOR);
+            }
+            return sManager;
+        }
+    }
+
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+
+        private static final int DATABASE_VERSION = 1;
+        private static final String COLUMN_KEYWORD = "keyword";
+        private static final String COLUMN_LAST_UPDATED_TIME = "last_updated_time";
+        private static final String HISTORY_DATABASE = "search_history.db";
+        private static final String HISTORY_TABLE = "search_history";
+
+        private DatabaseHelper(Context context) {
+            super(context, HISTORY_DATABASE, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + HISTORY_TABLE + " (" + COLUMN_KEYWORD + " TEXT NOT NULL, "
+                + COLUMN_LAST_UPDATED_TIME + " INTEGER)");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            //TODO: Doing database backup/restore data migration or upgrade with b/121987495
+
+            if (DEBUG) {
+                Log.w(TAG, "Upgrading database..., Old version = " + oldVersion
+                    + ", New version = " + newVersion);
+            }
+            db.execSQL("DROP TABLE IF EXISTS " + HISTORY_TABLE);
+            onCreate(db);
+        }
+    }
+
+    /**
+     * Get search history list with/without filter text.
+     * @param filter the filter text
+     * @return a list of search history
+     */
+    public List<String> getHistoryList(@Nullable String filter) {
+        synchronized (mLock) {
+            if (!TextUtils.isEmpty(filter)) {
+                final List<String> filterKeyword = Collections.synchronizedList(new ArrayList<>());
+                final String keyword = filter;
+                for (String history : mHistory) {
+                    if (history.contains(keyword)) {
+                        filterKeyword.add(history);
+                    }
+                }
+                return filterKeyword;
+            } else {
+                return Collections.synchronizedList(new ArrayList<>(mHistory));
+            }
+        }
+    }
+
+    /**
+     * Add search keyword text to list.
+     * @param keyword the text to be added
+     */
+    public void addHistory(String keyword) {
+        synchronized (mLock) {
+            if (mHistory.remove(keyword)) {
+                mHistory.add(0, keyword);
+                new DatabaseTask(keyword, DATABASE_OPERATION.UPDATE).executeOnExecutor(
+                    AsyncTask.SERIAL_EXECUTOR);
+            } else {
+                if (mHistory.size() >= mLimitedHistoryCount) {
+                    new DatabaseTask(mHistory.remove(mHistory.size() - 1),
+                        DATABASE_OPERATION.DELETE).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
+                        Boolean.FALSE);
+
+                    Log.w(TAG, "Over search history count !! keyword = " + keyword
+                        + "has been deleted");
+                }
+                mHistory.add(0, keyword);
+                new DatabaseTask(keyword, DATABASE_OPERATION.ADD).executeOnExecutor(
+                    AsyncTask.SERIAL_EXECUTOR);
+            }
+        }
+    }
+
+    /**
+     * Delete search keyword text from list.
+     * @param keyword the text to be deleted
+     */
+    public void deleteHistory(String keyword) {
+        synchronized (mLock) {
+            if (mHistory.remove(keyword)) {
+                new DatabaseTask(keyword, DATABASE_OPERATION.DELETE).executeOnExecutor(
+                    AsyncTask.SERIAL_EXECUTOR);
+            }
+        }
+    }
+
+    private class DatabaseTask extends AsyncTask<Object, Void, Object> {
+        private final String mKeyword;
+        private final DATABASE_OPERATION mOperation;
+
+        public DatabaseTask(String keyword, DATABASE_OPERATION operation) {
+            mKeyword = keyword;
+            mOperation = operation;
+        }
+
+        private Cursor getSortedHistoryList() {
+            final SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
+            queryBuilder.setTables(DatabaseHelper.HISTORY_TABLE);
+
+            return queryBuilder.query(mHelper.getReadableDatabase(), PROJECTION_HISTORY, null,
+                null, null, null, DatabaseHelper.COLUMN_LAST_UPDATED_TIME + " DESC");
+        }
+
+        private void addDatabaseData() {
+            final ContentValues values = new ContentValues();
+            values.put(DatabaseHelper.COLUMN_KEYWORD, mKeyword);
+            values.put(DatabaseHelper.COLUMN_LAST_UPDATED_TIME, System.currentTimeMillis());
+
+            final long rowId = mHelper.getWritableDatabase().insert(
+                DatabaseHelper.HISTORY_TABLE, null, values);
+            if (rowId == -1) {
+                Log.w(TAG, "Failed to add " + mKeyword + "to database!");
+            }
+
+            if (mListener != null) {
+                mListener.onAddChangedListener(rowId);
+            }
+        }
+
+        private void deleteDatabaseData() {
+            // We only care about the field of DatabaseHelper.COLUMN_KEYWORD for deleting
+            StringBuilder selection = new StringBuilder();
+            selection.append(DatabaseHelper.COLUMN_KEYWORD).append("=?");
+            final int numberOfRows = mHelper.getWritableDatabase().delete(
+                DatabaseHelper.HISTORY_TABLE, selection.toString(), new String[] {
+                    mKeyword });
+            if (numberOfRows == 0) {
+                Log.w(TAG, "Failed to delete " + mKeyword + "from database!");
+            }
+
+            if (mListener != null) {
+                mListener.onDeleteChangedListener(numberOfRows);
+            }
+        }
+
+        private void updateDatabaseData() {
+            // We just need to update the field DatabaseHelper.COLUMN_LAST_UPDATED_TIME,
+            // because we will sort by last modified when retrieving from database
+            ContentValues values = new ContentValues();
+            values.put(DatabaseHelper.COLUMN_LAST_UPDATED_TIME, System.currentTimeMillis());
+
+            StringBuilder selection = new StringBuilder();
+            selection.append(DatabaseHelper.COLUMN_KEYWORD).append("=?");
+            final int numberOfRows = mHelper.getWritableDatabase().update(
+                DatabaseHelper.HISTORY_TABLE, values, selection.toString(), new String[] {
+                    mKeyword });
+            if (numberOfRows == 0) {
+                Log.w(TAG, "Failed to update " + mKeyword + "to database!");
+            }
+        }
+
+        private void parseHistoryFromCursor(Cursor cursor) {
+            if (cursor == null) {
+                if (DEBUG) {
+                    Log.e(TAG, "Null cursor happens when building local search history List!");
+                }
+                return;
+            }
+            synchronized (mLock) {
+                mHistory.clear();
+                try {
+                    while (cursor.moveToNext()) {
+                        mHistory.add(cursor.getString(cursor.getColumnIndex(
+                            DatabaseHelper.COLUMN_KEYWORD)));
+                    }
+                } finally {
+                    cursor.close();
+                }
+            }
+        }
+
+        @Override
+        protected Void doInBackground(Object... params) {
+            if (!TextUtils.isEmpty(mKeyword)) {
+                switch (mOperation) {
+                    case ADD:
+                        addDatabaseData();
+                        break;
+                    case DELETE:
+                        deleteDatabaseData();
+                        break;
+                    case UPDATE:
+                        updateDatabaseData();
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            // params[0] is used to preventing reload twice when deleting over history count
+            if (params.length <= 0 || (params.length > 0 && ((Boolean)params[0]).booleanValue())) {
+                parseHistoryFromCursor(getSortedHistoryList());
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Object result) {
+            if (mListener != null) {
+                mListener.onPostExecute();
+            }
+        }
+    }
+
+    @VisibleForTesting
+    public void setDatabaseListener(DatabaseChangedListener listener) {
+        mListener = listener;
+    }
+
+    interface DatabaseChangedListener {
+        void onAddChangedListener(long longResult);
+        void onDeleteChangedListener(int intResult);
+        void onPostExecute();
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/documentsui/queries/SearchViewManager.java b/src/com/android/documentsui/queries/SearchViewManager.java
index fab5a93..c498329 100644
--- a/src/com/android/documentsui/queries/SearchViewManager.java
+++ b/src/com/android/documentsui/queries/SearchViewManager.java
@@ -17,12 +17,15 @@
 package com.android.documentsui.queries;
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
+import static com.android.documentsui.base.State.ACTION_GET_CONTENT;
+import static com.android.documentsui.base.State.ACTION_OPEN;
+import static com.android.documentsui.base.State.ActionType;
 
-import android.annotation.Nullable;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsContract;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
@@ -31,17 +34,23 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
-import android.widget.SearchView;
-import android.widget.SearchView.OnQueryTextListener;
+import android.view.ViewGroup;
 
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.widget.SearchView;
+import androidx.appcompat.widget.SearchView.OnQueryTextListener;
+
+import com.android.documentsui.MetricConsts;
+import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.documentsui.base.State;
 
 import java.util.Timer;
 import java.util.TimerTask;
@@ -60,6 +69,7 @@
 
     private final SearchManagerListener mListener;
     private final EventHandler<String> mCommandProcessor;
+    private final SearchChipViewManager mChipViewManager;
     private final Timer mTimer;
     private final Handler mUiHandler;
 
@@ -69,9 +79,12 @@
     @GuardedBy("mSearchLock")
     private @Nullable TimerTask mQueuedSearchTask;
     private @Nullable String mCurrentSearch;
+    private String mQueryContentFromIntent;
     private boolean mSearchExpanded;
     private boolean mIgnoreNextClose;
     private boolean mFullBar;
+    private boolean mIsHistorySearch;
+    private boolean mShowSearchBar;
 
     private Menu mMenu;
     private MenuItem mMenuItem;
@@ -80,15 +93,17 @@
     public SearchViewManager(
             SearchManagerListener listener,
             EventHandler<String> commandProcessor,
+            ViewGroup chipGroup,
             @Nullable Bundle savedState) {
-        this(listener, commandProcessor, savedState, new Timer(),
-                new Handler(Looper.getMainLooper()));
+        this(listener, commandProcessor, new SearchChipViewManager(chipGroup), savedState,
+                new Timer(), new Handler(Looper.getMainLooper()));
     }
 
     @VisibleForTesting
     protected SearchViewManager(
             SearchManagerListener listener,
             EventHandler<String> commandProcessor,
+            SearchChipViewManager chipViewManager,
             @Nullable Bundle savedState,
             Timer timer,
             Handler handler) {
@@ -100,10 +115,106 @@
         mCommandProcessor = commandProcessor;
         mTimer = timer;
         mUiHandler = handler;
-        mCurrentSearch = savedState != null ? savedState.getString(Shared.EXTRA_QUERY) : null;
+        mChipViewManager = chipViewManager;
+        mChipViewManager.setSearchChipViewManagerListener(this::onChipCheckedStateChanged);
+
+        if (savedState != null) {
+            mCurrentSearch = savedState.getString(Shared.EXTRA_QUERY);
+            mChipViewManager.restoreCheckedChipItems(savedState);
+        } else {
+            mCurrentSearch = null;
+        }
     }
 
-    public void install(Menu menu, boolean isFullBarSearch) {
+    private void onChipCheckedStateChanged(View v) {
+        mListener.onSearchChipStateChanged(v);
+        performSearch(mCurrentSearch);
+    }
+
+    /**
+     * Parse the query content from Intent. If the action is not {@link State#ACTION_GET_CONTENT}
+     * or {@link State#ACTION_OPEN}, don't perform search.
+     * @param intent the intent to parse.
+     * @param action the action to check.
+     * @return True, if get the query content from the intent. Otherwise, false.
+     */
+    public boolean parseQueryContentFromIntent(Intent intent, @ActionType int action) {
+        if (action == ACTION_OPEN || action == ACTION_GET_CONTENT) {
+            final String queryString = intent.getStringExtra(Intent.EXTRA_CONTENT_QUERY);
+            if (!TextUtils.isEmpty(queryString)) {
+                mQueryContentFromIntent = queryString;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Build the bundle of query arguments.
+     * Example: search string and mime types
+     *
+     * @return the bundle of query arguments
+     */
+    public Bundle buildQueryArgs() {
+        final Bundle queryArgs = new Bundle();
+        if (!TextUtils.isEmpty(mCurrentSearch)) {
+            queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, mCurrentSearch);
+        }
+
+        final String[] checkedMimeTypes = mChipViewManager.getCheckedMimeTypes();
+        if (checkedMimeTypes != null && checkedMimeTypes.length > 0) {
+            queryArgs.putStringArray(DocumentsContract.QUERY_ARG_MIME_TYPES, checkedMimeTypes);
+        }
+        return queryArgs;
+    }
+
+    /**
+     * Initialize the search chips base on the acceptMimeTypes.
+     *
+     * @param acceptMimeTypes use to filter chips
+     */
+    public void initChipSets(String[] acceptMimeTypes) {
+        mChipViewManager.initChipSets(acceptMimeTypes);
+    }
+
+    /**
+     * Update the search chips base on the acceptMimeTypes.
+     * If the count of matched chips is less than two, we will
+     * hide the chip row.
+     *
+     * @param acceptMimeTypes use to filter chips
+     */
+    public void updateChips(String[] acceptMimeTypes) {
+        mChipViewManager.updateChips(acceptMimeTypes);
+    }
+
+    /**
+     * Bind chip data in ChipViewManager on other view groups
+     *
+     * @param chipGroup target view group for bind ChipViewManager data
+     */
+    public void bindChips(ViewGroup chipGroup) {
+        mChipViewManager.bindMirrorGroup(chipGroup);
+    }
+
+    /**
+     * Click behavior when chip in synced chip group click.
+     *
+     * @param data SearchChipData synced in mirror group
+     */
+    public void onMirrorChipClick(SearchChipData data) {
+        mChipViewManager.onMirrorChipClick(data);
+        mSearchView.clearFocus();
+    }
+
+    /**
+     * Initailize search view by option menu.
+     *
+     * @param menu the menu include search view
+     * @param isFullBarSearch whether hide other menu when search view expand
+     * @param isShowSearchBar whether replace collapsed search view by search hint text
+     */
+    public void install(Menu menu, boolean isFullBarSearch, boolean isShowSearchBar) {
         mMenu = menu;
         mMenuItem = mMenu.findItem(R.id.option_menu_search);
         mSearchView = (SearchView) mMenuItem.getActionView();
@@ -112,16 +223,20 @@
         mSearchView.setOnCloseListener(this);
         mSearchView.setOnSearchClickListener(this);
         mSearchView.setOnQueryTextFocusChangeListener(this);
-
-        mFullBar = isFullBarSearch;
-        if (mFullBar) {
-            mMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
-                    | MenuItem.SHOW_AS_ACTION_ALWAYS);
-            mMenuItem.setOnActionExpandListener(this);
-            mSearchView.setMaxWidth(Integer.MAX_VALUE);
+        final View clearButton = mSearchView.findViewById(R.id.search_close_btn);
+        if (clearButton != null) {
+            clearButton.setOnClickListener(v -> {
+                mSearchView.setQuery("", false);
+                mListener.onSearchViewClearClicked();
+            });
         }
 
-        restoreSearch();
+        mFullBar = isFullBarSearch;
+        mShowSearchBar = isShowSearchBar;
+        mSearchView.setMaxWidth(Integer.MAX_VALUE);
+        mMenuItem.setOnActionExpandListener(this);
+
+        restoreSearch(false);
     }
 
     /**
@@ -129,7 +244,7 @@
      * is done before onPrepareOptionsMenu(Menu menu) that is overriding the icons visibility.
      */
     public void updateMenu() {
-        if (isSearching() && mFullBar) {
+        if (isExpanded() && mFullBar) {
             mMenu.setGroupVisible(R.id.group_hide_when_searching, false);
         }
     }
@@ -139,7 +254,9 @@
      */
     public void update(DocumentStack stack) {
         if (mMenuItem == null) {
-            if (DEBUG) Log.d(TAG, "update called before Search MenuItem installed.");
+            if (DEBUG) {
+                Log.d(TAG, "update called before Search MenuItem installed.");
+            }
             return;
         }
 
@@ -176,12 +293,14 @@
         }
 
         final RootInfo root = stack != null ? stack.getRoot() : null;
-        if (root == null || (root.flags & Root.FLAG_SUPPORTS_SEARCH) == 0) {
+        if (root == null || !root.supportsSearch()) {
             supportsSearch = false;
         }
 
         if (mMenuItem == null) {
-            if (DEBUG) Log.d(TAG, "showMenu called before Search MenuItem installed.");
+            if (DEBUG) {
+                Log.d(TAG, "showMenu called before Search MenuItem installed.");
+            }
             return;
         }
 
@@ -189,7 +308,10 @@
             mCurrentSearch = null;
         }
 
-        mMenuItem.setVisible(supportsSearch);
+        // Recent root show open search bar, do not show duplicate search icon.
+        mMenuItem.setVisible(supportsSearch && (!stack.isRecents() || !mShowSearchBar));
+
+        mChipViewManager.setChipsRowVisible(supportsSearch && root.supportsMimeTypesSearch());
     }
 
     /**
@@ -198,17 +320,18 @@
      * @return True if it cancels search. False if it does not operate search currently.
      */
     public boolean cancelSearch() {
-        if (isExpanded() || isSearching()) {
+        if (mSearchView != null && (isExpanded() || isSearching())) {
             cancelQueuedSearch();
             // If the query string is not empty search view won't get iconified
             mSearchView.setQuery("", false);
 
             if (mFullBar) {
-               onClose();
+                onClose();
             } else {
                 // Causes calling onClose(). onClose() is triggering directory content update.
                 mSearchView.setIconified(true);
             }
+
             return true;
         }
         return false;
@@ -222,6 +345,7 @@
             mQueuedSearchTask = null;
             mUiHandler.removeCallbacks(mQueuedSearchRunnable);
             mQueuedSearchRunnable = null;
+            mIsHistorySearch = false;
         }
     }
 
@@ -229,19 +353,24 @@
      * Sets search view into the searching state. Used to restore state after device orientation
      * change.
      */
-    private void restoreSearch() {
-        if (isSearching()) {
-            if (mFullBar) {
-                mMenuItem.expandActionView();
-            } else {
-                mSearchView.setIconified(false);
-            }
-            onSearchExpanded();
+    public void restoreSearch(boolean keepFocus) {
+        if (isTextSearching()) {
+            onSearchBarClicked();
             mSearchView.setQuery(mCurrentSearch, false);
-            mSearchView.clearFocus();
+
+            if (keepFocus) {
+                mSearchView.requestFocus();
+            } else {
+                mSearchView.clearFocus();
+            }
         }
     }
 
+    public void onSearchBarClicked() {
+        mMenuItem.expandActionView();
+        onSearchExpanded();
+    }
+
     private void onSearchExpanded() {
         mSearchExpanded = true;
         if (mFullBar) {
@@ -253,6 +382,7 @@
 
     /**
      * Clears the search. Triggers refreshing of the directory content.
+     *
      * @return True if the default behavior of clearing/dismissing SearchView should be overridden.
      *         False otherwise.
      */
@@ -265,7 +395,9 @@
         }
 
         // Refresh the directory if a search was done
-        if (mCurrentSearch != null) {
+        if (mCurrentSearch != null || mChipViewManager.hasCheckedItems()) {
+            // Clear checked chips
+            mChipViewManager.clearCheckedChips();
             mCurrentSearch = null;
             mListener.onSearchChanged(mCurrentSearch);
         }
@@ -282,10 +414,12 @@
 
     /**
      * Called when owning activity is saving state to be used to restore state during creation.
+     *
      * @param state Bundle to save state too
      */
     public void onSaveInstanceState(Bundle state) {
         state.putString(Shared.EXTRA_QUERY, mCurrentSearch);
+        mChipViewManager.onSaveInstanceState(state);
     }
 
     /**
@@ -305,10 +439,11 @@
         } else {
             cancelQueuedSearch();
             // Don't kick off a search if we've already finished it.
-            if (mCurrentSearch != query) {
+            if (!TextUtils.equals(mCurrentSearch, query)) {
                 mCurrentSearch = query;
                 mListener.onSearchChanged(mCurrentSearch);
             }
+            recordHistory();
             mSearchView.clearFocus();
         }
 
@@ -320,13 +455,14 @@
      */
     @Override
     public void onFocusChange(View v, boolean hasFocus) {
-        if (!hasFocus) {
+        if (!hasFocus && !mChipViewManager.hasCheckedItems()) {
             if (mCurrentSearch == null) {
                 mSearchView.setIconified(true);
             } else if (TextUtils.isEmpty(mSearchView.getQuery())) {
                 cancelSearch();
             }
         }
+        mListener.onSearchViewFocusChanged(hasFocus);
     }
 
     @VisibleForTesting
@@ -341,6 +477,7 @@
                         if (mCurrentSearch != null && mCurrentSearch.isEmpty()) {
                             mCurrentSearch = null;
                         }
+                        logTextSearchMetric();
                         mListener.onSearchChanged(mCurrentSearch);
                     };
                     mUiHandler.post(mQueuedSearchRunnable);
@@ -351,13 +488,20 @@
 
     @Override
     public boolean onQueryTextChange(String newText) {
+        //Skip first search when search expanded
+        if (!(mCurrentSearch == null && newText.isEmpty())) {
+            performSearch(newText);
+        }
+        return true;
+    }
+
+    private void performSearch(String newText) {
         cancelQueuedSearch();
         synchronized (mSearchLock) {
             mQueuedSearchTask = createSearchTask(newText);
 
             mTimer.schedule(mQueuedSearchTask, SEARCH_DELAY_MS);
         }
-        return true;
     }
 
     @Override
@@ -381,17 +525,93 @@
         return mCurrentSearch;
     }
 
+    /**
+     * Get current text on search view.
+     *
+     * @return  Cuttent string on search view
+     */
+    public String getSearchViewText() {
+        return mSearchView.getQuery().toString();
+    }
+
+    /**
+     * Record current search for history.
+     */
+    public void recordHistory() {
+        SearchHistoryManager.getInstance(
+                mSearchView.getContext().getApplicationContext()).addHistory(mCurrentSearch);
+    }
+
+    /**
+     * Remove specific text item in history list.
+     *
+     * @param history target string for removed.
+     */
+    public void removeHistory(String history) {
+        SearchHistoryManager.getInstance(
+                mSearchView.getContext().getApplicationContext()).deleteHistory(history);
+    }
+
+    private void logTextSearchMetric() {
+        if (isTextSearching()) {
+            Metrics.logUserAction(mIsHistorySearch
+                    ? MetricConsts.USER_ACTION_SEARCH_HISTORY : MetricConsts.USER_ACTION_SEARCH);
+            Metrics.logSearchType(mIsHistorySearch
+                    ? MetricConsts.TYPE_SEARCH_HISTORY : MetricConsts.TYPE_SEARCH_STRING);
+            mIsHistorySearch = false;
+        }
+    }
+
+    /**
+     * Get the query content from intent.
+     * @return If has query content, return the query content. Otherwise, return null
+     * @see #parseQueryContentFromIntent(Intent, int)
+     */
+    public String getQueryContentFromIntent() {
+        return mQueryContentFromIntent;
+    }
+
+    public void setCurrentSearch(String queryString) {
+        mCurrentSearch = queryString;
+    }
+
+    /**
+     * Set next search type is history search.
+     */
+    public void setHistorySearch() {
+        mIsHistorySearch = true;
+    }
+
     public boolean isSearching() {
+        return mCurrentSearch != null || mChipViewManager.hasCheckedItems();
+    }
+
+    private boolean isTextSearching() {
         return mCurrentSearch != null;
     }
 
+    public boolean hasCheckedChip() {
+        return mChipViewManager.hasCheckedItems();
+    }
+
     public boolean isExpanded() {
         return mSearchExpanded;
     }
 
     public interface SearchManagerListener {
         void onSearchChanged(@Nullable String query);
+
         void onSearchFinished();
+
         void onSearchViewChanged(boolean opened);
+
+        void onSearchChipStateChanged(View v);
+
+        void onSearchViewFocusChanged(boolean hasFocus);
+
+        /**
+         * Call back when search view clear button clicked
+         */
+        void onSearchViewClearClicked();
     }
 }
diff --git a/src/com/android/documentsui/roots/GetRootDocumentTask.java b/src/com/android/documentsui/roots/GetRootDocumentTask.java
index 84b5812..b835f71 100644
--- a/src/com/android/documentsui/roots/GetRootDocumentTask.java
+++ b/src/com/android/documentsui/roots/GetRootDocumentTask.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.roots;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.app.Activity;
 import android.util.Log;
 
diff --git a/src/com/android/documentsui/roots/LoadFirstRootTask.java b/src/com/android/documentsui/roots/LoadFirstRootTask.java
new file mode 100644
index 0000000..ef91b49
--- /dev/null
+++ b/src/com/android/documentsui/roots/LoadFirstRootTask.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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.documentsui.roots;
+
+import android.app.Activity;
+import android.net.Uri;
+
+import com.android.documentsui.AbstractActionHandler.CommonAddons;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.State;
+
+import java.util.Collection;
+
+public final class LoadFirstRootTask<T extends Activity & CommonAddons>
+        extends LoadRootTask<T> {
+
+    public LoadFirstRootTask(T activity, ProvidersAccess providers, State state, Uri rootUri) {
+        super(activity, providers, state, rootUri);
+    }
+
+    @Override
+    protected String getRootId(Uri rootUri) {
+        final String authority = rootUri.getAuthority();
+        String rootId = null;
+
+        final Collection<RootInfo> roots = mProviders.getRootsForAuthorityBlocking(authority);
+        if (!roots.isEmpty()) {
+            rootId = roots.iterator().next().rootId;
+        }
+
+        return rootId;
+    }
+}
diff --git a/src/com/android/documentsui/roots/LoadRootTask.java b/src/com/android/documentsui/roots/LoadRootTask.java
index 308bb45..a146090 100644
--- a/src/com/android/documentsui/roots/LoadRootTask.java
+++ b/src/com/android/documentsui/roots/LoadRootTask.java
@@ -28,14 +28,14 @@
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 
-public final class LoadRootTask<T extends Activity & CommonAddons>
+public class LoadRootTask<T extends Activity & CommonAddons>
         extends PairedTask<T, Void, RootInfo> {
     private static final String TAG = "LoadRootTask";
 
-    private final State mState;
-    private final ProvidersAccess mProviders;
-    private final Uri mRootUri;
+    protected final ProvidersAccess mProviders;
 
+    private final State mState;
+    private final Uri mRootUri;
 
     public LoadRootTask(T activity, ProvidersAccess providers, State state, Uri rootUri) {
         super(activity);
@@ -46,20 +46,27 @@
 
     @Override
     protected RootInfo run(Void... params) {
-        if (DEBUG) Log.d(TAG, "Loading root: " + mRootUri);
+        if (DEBUG) {
+            Log.d(TAG, "Loading root: " + mRootUri);
+        }
 
-        String rootId = DocumentsContract.getRootId(mRootUri);
-        return mProviders.getRootOneshot(mRootUri.getAuthority(), rootId);
+        return mProviders.getRootOneshot(mRootUri.getAuthority(), getRootId(mRootUri));
     }
 
     @Override
     protected void finish(RootInfo root) {
         if (root != null) {
-            if (DEBUG) Log.d(TAG, "Loaded root: " + root);
+            if (DEBUG) {
+                Log.d(TAG, "Loaded root: " + root);
+            }
             mOwner.onRootPicked(root);
         } else {
             Log.w(TAG, "Failed to find root: " + mRootUri);
             mOwner.finish();
         }
     }
+
+    protected String getRootId(Uri rootUri) {
+        return DocumentsContract.getRootId(rootUri);
+    }
 }
diff --git a/src/com/android/documentsui/roots/ProvidersAccess.java b/src/com/android/documentsui/roots/ProvidersAccess.java
index 93db10a..aa4b530 100644
--- a/src/com/android/documentsui/roots/ProvidersAccess.java
+++ b/src/com/android/documentsui/roots/ProvidersAccess.java
@@ -89,6 +89,12 @@
                 continue;
             }
 
+            if (state.action == State.ACTION_OPEN_TREE && root.isRecents()) {
+                if (VERBOSE) Log.v(
+                        tag, "Excluding recent root because: ACTION_OPEN_TREE.");
+                continue;
+            }
+
             if (!state.showAdvanced && root.isAdvanced()) {
                 if (VERBOSE) Log.v(tag, "Excluding root because: unwanted advanced device.");
                 continue;
@@ -133,7 +139,9 @@
             matching.add(root);
         }
 
-        if (DEBUG) Log.d(tag, "Matched roots: " + matching);
+        if (DEBUG) {
+            Log.d(tag, "Matched roots: " + matching);
+        }
         return matching;
     }
 }
diff --git a/src/com/android/documentsui/roots/ProvidersCache.java b/src/com/android/documentsui/roots/ProvidersCache.java
index 1527918..bd3ca1f 100644
--- a/src/com/android/documentsui/roots/ProvidersCache.java
+++ b/src/com/android/documentsui/roots/ProvidersCache.java
@@ -16,6 +16,8 @@
 
 package com.android.documentsui.roots;
 
+import static android.provider.DocumentsContract.QUERY_ARG_MIME_TYPES;
+
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
@@ -37,7 +39,7 @@
 import android.os.SystemClock;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Root;
-import android.support.v4.content.LocalBroadcastManager;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import android.util.Log;
 
 import com.android.documentsui.DocumentsApplication;
@@ -46,12 +48,12 @@
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
-import com.android.internal.annotations.GuardedBy;
+import androidx.annotation.GuardedBy;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -107,13 +109,14 @@
 
         // Create a new anonymous "Recents" RootInfo. It's a faker.
         mRecentsRoot = new RootInfo() {{
-                // Special root for recents
-                derivedIcon = R.drawable.ic_root_recent;
-                derivedType = RootInfo.TYPE_RECENTS;
-                flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD;
-                title = mContext.getString(R.string.root_recent);
-                availableBytes = -1;
-            }};
+            // Special root for recents
+            derivedIcon = R.drawable.ic_root_recent;
+            derivedType = RootInfo.TYPE_RECENTS;
+            flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_SEARCH;
+            queryArgs = QUERY_ARG_MIME_TYPES;
+            title = mContext.getString(R.string.root_recent);
+            availableBytes = -1;
+        }};
     }
 
     private class RootsChangedObserver extends ContentObserver {
@@ -127,7 +130,9 @@
                 Log.w(TAG, "Received onChange event for null uri. Skipping.");
                 return;
             }
-            if (DEBUG) Log.i(TAG, "Updating roots due to change at " + uri);
+            if (DEBUG) {
+                Log.i(TAG, "Updating roots due to change at " + uri);
+            }
             updateAuthorityAsync(uri.getAuthority());
         }
     }
@@ -226,7 +231,9 @@
             if (!mStoppedAuthorities.contains(authority)) {
                 return;
             }
-            if (DEBUG) Log.d(TAG, "Loading stopped authority " + authority);
+            if (DEBUG) {
+                Log.d(TAG, "Loading stopped authority " + authority);
+            }
             mRoots.replaceValues(authority, loadRootsForAuthority(resolver, authority, true));
             mStoppedAuthorities.remove(authority);
         }
@@ -311,8 +318,8 @@
             // if forceRefresh is false.
             return roots;
         } finally {
-            IoUtils.closeQuietly(cursor);
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(client);
         }
 
         // Cache these freshly parsed roots over in the long-lived system
diff --git a/src/com/android/documentsui/roots/RootsLoader.java b/src/com/android/documentsui/roots/RootsLoader.java
index 3a34807..f197c77 100644
--- a/src/com/android/documentsui/roots/RootsLoader.java
+++ b/src/com/android/documentsui/roots/RootsLoader.java
@@ -16,12 +16,13 @@
 
 package com.android.documentsui.roots;
 
-import android.content.AsyncTaskLoader;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.support.v4.content.LocalBroadcastManager;
+
+import androidx.loader.content.AsyncTaskLoader;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
diff --git a/src/com/android/documentsui/selection/BandPredicate.java b/src/com/android/documentsui/selection/BandPredicate.java
deleted file mode 100644
index 48b154b..0000000
--- a/src/com/android/documentsui/selection/BandPredicate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-import android.view.View;
-
-/**
- * Provides a means of controlling when and where band selection is initiated.
- * This can be used to permit band initiation in non-empty areas, like in the whitespace of
- * a bound view. This is especially useful when there is no empty space between items.
- */
-public abstract class BandPredicate {
-
-    /** @return true if band selection can be initiated in response to the {@link MotionEvent}. */
-    public abstract boolean canInitiate(MotionEvent e);
-
-    /**
-     * A BandPredicate that allows initiation of band selection only in areas of RecyclerView
-     * that have {@link RecyclerView#NO_POSITION}. In most cases, this will be the empty areas
-     * between views.
-     */
-    public static final class NoPositionBandPredicate extends BandPredicate {
-
-        private final RecyclerView mRecView;
-
-        public NoPositionBandPredicate(RecyclerView recView) {
-            checkArgument(recView != null);
-
-            mRecView = recView;
-        }
-
-        @Override
-        public boolean canInitiate(MotionEvent e) {
-            View itemView = mRecView.findChildViewUnder(e.getX(), e.getY());
-            int position = itemView != null
-                    ? mRecView.getChildAdapterPosition(itemView)
-                    : RecyclerView.NO_POSITION;
-
-            return position == RecyclerView.NO_POSITION;
-        }
-    };
-}
diff --git a/src/com/android/documentsui/selection/BandSelectionHelper.java b/src/com/android/documentsui/selection/BandSelectionHelper.java
deleted file mode 100644
index 554dcf4..0000000
--- a/src/com/android/documentsui/selection/BandSelectionHelper.java
+++ /dev/null
@@ -1,401 +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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-import static android.support.v4.util.Preconditions.checkState;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Build;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
-import android.support.v7.widget.RecyclerView.OnScrollListener;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Provides mouse driven band-selection support when used in conjunction with a {@link RecyclerView}
- * instance. This class is responsible for rendering a band overlay and manipulating selection
- * status of the items it intersects with.
- *
- * <p> Given the recycling nature of RecyclerView items that have scrolled off-screen would not
- * be selectable with a band that itself was partially rendered off-screen. To address this,
- * BandSelectionController builds a model of the list/grid information presented by RecyclerView as
- * the user interacts with items using their pointer (and the band). Selectable items that intersect
- * with the band, both on and off screen, are selected on pointer up.
- */
-public class BandSelectionHelper implements OnItemTouchListener {
-
-    static final boolean DEBUG = false;
-    static final String TAG = "BandController";
-
-    private final BandHost mHost;
-    private final StableIdProvider mStableIds;
-    private final RecyclerView.Adapter<?> mAdapter;
-    private final SelectionHelper mSelectionHelper;
-    private final SelectionPredicate mSelectionPredicate;
-    private final BandPredicate mBandPredicate;
-    private final ContentLock mLock;
-    private final Runnable mViewScroller;
-    private final GridModel.SelectionObserver mGridObserver;
-    private final List<Runnable> mBandStartedListeners = new ArrayList<>();
-
-    @Nullable private Rect mBounds;
-    @Nullable private Point mCurrentPosition;
-    @Nullable private Point mOrigin;
-    @Nullable private GridModel mModel;
-
-    public BandSelectionHelper(
-            BandHost host,
-            RecyclerView.Adapter<?> adapter,
-            StableIdProvider stableIds,
-            SelectionHelper selectionHelper,
-            SelectionPredicate selectionPredicate,
-            BandPredicate bandPredicate,
-            ContentLock lock) {
-
-        checkArgument(host != null);
-        checkArgument(adapter != null);
-        checkArgument(stableIds != null);
-        checkArgument(selectionHelper != null);
-        checkArgument(selectionPredicate != null);
-        checkArgument(bandPredicate != null);
-        checkArgument(lock != null);
-
-        mHost = host;
-        mStableIds = stableIds;
-        mAdapter = adapter;
-        mSelectionHelper = selectionHelper;
-        mSelectionPredicate = selectionPredicate;
-        mBandPredicate = bandPredicate;
-        mLock = lock;
-
-        mHost.addOnScrollListener(
-                new OnScrollListener() {
-                    @Override
-                    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-                        BandSelectionHelper.this.onScrolled(recyclerView, dx, dy);
-                    }
-                });
-
-        mViewScroller = new ViewAutoScroller(
-                new ScrollHost() {
-                    @Override
-                    public Point getCurrentPosition() {
-                        return mCurrentPosition;
-                    }
-
-                    @Override
-                    public int getViewHeight() {
-                        return mHost.getHeight();
-                    }
-
-                    @Override
-                    public boolean isActive() {
-                        return BandSelectionHelper.this.isActive();
-                    }
-                },
-                host);
-
-        mAdapter.registerAdapterDataObserver(
-                new RecyclerView.AdapterDataObserver() {
-                    @Override
-                    public void onChanged() {
-                        if (isActive()) {
-                            endBandSelect();
-                        }
-                    }
-
-                    @Override
-                    public void onItemRangeChanged(
-                            int startPosition, int itemCount, Object payload) {
-                        // No change in position. Ignoring.
-                    }
-
-                    @Override
-                    public void onItemRangeInserted(int startPosition, int itemCount) {
-                        if (isActive()) {
-                            endBandSelect();
-                        }
-                    }
-
-                    @Override
-                    public void onItemRangeRemoved(int startPosition, int itemCount) {
-                        assert(startPosition >= 0);
-                        assert(itemCount > 0);
-
-                        // TODO: Should update grid model.
-                    }
-
-                    @Override
-                    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-                        throw new UnsupportedOperationException();
-                    }
-                });
-
-        mGridObserver = new GridModel.SelectionObserver() {
-                @Override
-                public void onSelectionChanged(Set<String> updatedSelection) {
-                    mSelectionHelper.setProvisionalSelection(updatedSelection);
-                }
-            };
-    }
-
-    @VisibleForTesting
-    boolean isActive() {
-        boolean active = mModel != null;
-        if (Build.IS_DEBUGGABLE && active) {
-            mLock.checkLocked();
-        }
-        return active;
-    }
-
-    /**
-     * Adds a new listener to be notified when band is created.
-     */
-    public void addOnBandStartedListener(Runnable listener) {
-        checkArgument(listener != null);
-
-        mBandStartedListeners.add(listener);
-    }
-
-    /**
-     * Removes listener. No-op if listener was not previously installed.
-     */
-    public void removeOnBandStartedListener(Runnable listener) {
-        mBandStartedListeners.remove(listener);
-    }
-
-    /**
-     * Clients must call reset when there are any material changes to the layout of items
-     * in RecyclerView.
-     */
-    public void reset() {
-        if (!isActive()) {
-            return;
-        }
-
-        mHost.hideBand();
-        mModel.stopCapturing();
-        mModel.onDestroy();
-        mModel = null;
-        mOrigin = null;
-        mLock.unblock();
-    }
-
-    boolean shouldStart(MotionEvent e) {
-        // Don't start, or extend bands on non-left clicks.
-        if (!MotionEvents.isPrimaryButtonPressed(e)) {
-            return false;
-        }
-
-        // TODO: Refactor to NOT have side-effects on this "should" method.
-        // Weird things happen if we keep up band select
-        // when touch events happen.
-        if (isActive() && !MotionEvents.isMouseEvent(e)) {
-            endBandSelect();
-            return false;
-        }
-
-        // b/30146357 && b/23793622. onInterceptTouchEvent does not dispatch events to onTouchEvent
-        // unless the event is != ACTION_DOWN. Thus, we need to actually start band selection when
-        // mouse moves, or else starting band selection on mouse down can cause problems as events
-        // don't get routed correctly to onTouchEvent.
-        return !isActive()
-                && MotionEvents.isActionMove(e)
-                // the initial button move via mouse-touch (ie. down press)
-                // The adapter inserts items for UI layout purposes that aren't
-                // associated with files. Checking against actual modelIds count
-                // effectively ignores those UI layout items.
-                && !mStableIds.getStableIds().isEmpty()
-                && mBandPredicate.canInitiate(e);
-    }
-
-    public boolean shouldStop(MotionEvent e) {
-        return isActive()
-                && MotionEvents.isMouseEvent(e)
-                && (MotionEvents.isActionUp(e)
-                        || MotionEvents.isActionPointerUp(e)
-                        || MotionEvents.isActionCancel(e));
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(RecyclerView unused, MotionEvent e) {
-        if (shouldStart(e)) {
-            if (!MotionEvents.isCtrlKeyPressed(e)) {
-                mSelectionHelper.clearSelection();
-            }
-
-            startBandSelect(MotionEvents.getOrigin(e));
-            return isActive();
-        }
-
-        if (shouldStop(e)) {
-            endBandSelect();
-            checkState(mModel == null);
-            // fall through to return false, because the band eeess done!
-        }
-
-        return false;
-    }
-
-    /**
-     * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
-     * @param input
-     */
-    @Override
-    public void onTouchEvent(RecyclerView unused, MotionEvent e) {
-        if (shouldStop(e)) {
-            endBandSelect();
-            return;
-        }
-
-        // We shouldn't get any events in this method when band select is not active,
-        // but it turns some guests show up late to the party.
-        // Probably happening when a re-layout is happening to the ReyclerView (ie. Pull-To-Refresh)
-        if (!isActive()) {
-            return;
-        }
-
-        assert MotionEvents.isActionMove(e);
-
-        mCurrentPosition = MotionEvents.getOrigin(e);
-        mModel.resizeSelection(mCurrentPosition);
-
-        scrollViewIfNecessary();
-        resizeBand();
-    }
-
-    @Override
-    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
-
-    /**
-     * Starts band select by adding the drawable to the RecyclerView's overlay.
-     */
-    private void startBandSelect(Point origin) {
-        if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
-
-        reset();
-        mModel = new GridModel(mHost, mStableIds, mSelectionPredicate);
-        mModel.addOnSelectionChangedListener(mGridObserver);
-
-        mLock.block();
-        notifyBandStarted();
-        mOrigin = origin;
-        mModel.startCapturing(mOrigin);
-    }
-
-    private void notifyBandStarted() {
-        for (Runnable listener : mBandStartedListeners) {
-            listener.run();
-        }
-    }
-
-    private void scrollViewIfNecessary() {
-        mHost.removeCallback(mViewScroller);
-        mViewScroller.run();
-        mHost.invalidateView();
-    }
-
-    /**
-     * Resizes the band select rectangle by using the origin and the current pointer position as
-     * two opposite corners of the selection.
-     */
-    private void resizeBand() {
-        mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
-                Math.min(mOrigin.y, mCurrentPosition.y),
-                Math.max(mOrigin.x, mCurrentPosition.x),
-                Math.max(mOrigin.y, mCurrentPosition.y));
-
-        mHost.showBand(mBounds);
-    }
-
-    /**
-     * Ends band select by removing the overlay.
-     */
-    private void endBandSelect() {
-        if (DEBUG) Log.d(TAG, "Ending band select.");
-
-        // TODO: Currently when a band select operation ends outside
-        // of an item (e.g. in the empty area between items),
-        // getPositionNearestOrigin may return an unselected item.
-        // Since the point of this code is to establish the
-        // anchor point for subsequent range operations (SHIFT+CLICK)
-        // we really want to do a better job figuring out the last
-        // item selected (and nearest to the cursor).
-        int firstSelected = mModel.getPositionNearestOrigin();
-        if (firstSelected != GridModel.NOT_SET
-                && mSelectionHelper.isSelected(mStableIds.getStableId(firstSelected))) {
-            // Establish the band selection point as range anchor. This
-            // allows touch and keyboard based selection activities
-            // to be based on the band selection anchor point.
-            mSelectionHelper.anchorRange(firstSelected);
-        }
-
-        mSelectionHelper.mergeProvisionalSelection();
-        reset();
-    }
-
-    /**
-     * @see RecyclerView.OnScrollListener
-     */
-    private void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-        if (!isActive()) {
-            return;
-        }
-
-        // Adjust the y-coordinate of the origin the opposite number of pixels so that the
-        // origin remains in the same place relative to the view's items.
-        mOrigin.y -= dy;
-        resizeBand();
-    }
-
-    /**
-     * Provides functionality for BandController. Exists primarily to tests that are
-     * fully isolated from RecyclerView.
-     */
-    public static abstract class BandHost extends ScrollerCallbacks {
-        public abstract void showBand(Rect rect);
-        public abstract void hideBand();
-        public abstract void addOnScrollListener(RecyclerView.OnScrollListener listener);
-        public abstract void removeOnScrollListener(RecyclerView.OnScrollListener listener);
-        public abstract int getHeight();
-        public abstract void invalidateView();
-        public abstract Point createAbsolutePoint(Point relativePoint);
-        public abstract Rect getAbsoluteRectForChildViewAt(int index);
-        public abstract int getAdapterPositionAt(int index);
-        public abstract int getColumnCount();
-        public abstract int getChildCount();
-        public abstract int getVisibleChildCount();
-        /**
-         * @return true if the item at adapter position is attached to a view.
-         */
-        public abstract boolean hasView(int adapterPosition);
-    }
-}
diff --git a/src/com/android/documentsui/selection/ContentLock.java b/src/com/android/documentsui/selection/ContentLock.java
deleted file mode 100644
index 5cc3132..0000000
--- a/src/com/android/documentsui/selection/ContentLock.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkState;
-import static com.android.documentsui.selection.Shared.DEBUG;
-import static com.android.documentsui.selection.Shared.TAG;
-
-import android.annotation.MainThread;
-import android.annotation.Nullable;
-import android.content.Loader;
-import android.util.Log;
-
-/**
- * ContentLock provides a mechanism to block content from reloading while selection
- * activities like gesture and band selection are active. Clients using live data
- * (data loaded, for example by a {@link Loader}), should route calls to load
- * content through this lock using {@link ContentLock#runWhenUnlocked(Runnable)}.
- */
-public final class ContentLock {
-
-    private int mLocks = 0;
-    private @Nullable Runnable mCallback;
-
-    /**
-     * Increment the block count by 1
-     */
-    @MainThread
-    public synchronized void block() {
-        mLocks++;
-        if (DEBUG) Log.v(TAG, "Incremented content lock count to " + mLocks + ".");
-    }
-
-    /**
-     * Decrement the block count by 1; If no other object is trying to block and there exists some
-     * callback, that callback will be run
-     */
-    @MainThread
-    public synchronized void unblock() {
-        checkState(mLocks > 0);
-
-        mLocks--;
-        if (DEBUG) Log.v(TAG, "Decremented content lock count to " + mLocks + ".");
-
-        if (mLocks == 0 && mCallback != null) {
-            mCallback.run();
-            mCallback = null;
-        }
-    }
-
-    /**
-     * Attempts to run the given Runnable if not-locked, or else the Runnable is set to be ran next
-     * (replacing any previous set Runnables).
-     */
-    public synchronized void runWhenUnlocked(Runnable runnable) {
-        if (mLocks == 0) {
-            runnable.run();
-        } else {
-            mCallback = runnable;
-        }
-    }
-
-    /**
-     * Returns true if locked.
-     */
-    synchronized boolean isLocked() {
-        return mLocks > 0;
-    }
-
-    /**
-     * Allows other selection code to perform a precondition check asserting the state is locked.
-     */
-    final void checkLocked() {
-        checkState(isLocked());
-    }
-
-    /**
-     * Allows other selection code to perform a precondition check asserting the state is unlocked.
-     */
-    final void checkUnlocked() {
-        checkState(!isLocked());
-    }
-}
diff --git a/src/com/android/documentsui/selection/DefaultBandHost.java b/src/com/android/documentsui/selection/DefaultBandHost.java
deleted file mode 100644
index 6760706..0000000
--- a/src/com/android/documentsui/selection/DefaultBandHost.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.annotation.DrawableRes;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.View;
-
-import com.android.documentsui.selection.BandSelectionHelper.BandHost;
-
-/**
- * RecyclerView backed {@link BandHost}.
- */
-public final class DefaultBandHost extends BandHost {
-
-    private final RecyclerView mRecView;
-    private final Drawable mBand;
-
-    private boolean mIsOverlayShown;
-
-    public DefaultBandHost(RecyclerView recView, @DrawableRes int bandOverlayId) {
-
-        checkArgument(recView != null);
-
-        mRecView = recView;
-        mBand = mRecView.getContext().getTheme().getDrawable(bandOverlayId);
-
-        checkArgument(mBand != null);
-    }
-
-    @Override
-    public int getAdapterPositionAt(int index) {
-        return mRecView.getChildAdapterPosition(mRecView.getChildAt(index));
-    }
-
-    @Override
-    public void addOnScrollListener(RecyclerView.OnScrollListener listener) {
-        mRecView.addOnScrollListener(listener);
-    }
-
-    @Override
-    public void removeOnScrollListener(RecyclerView.OnScrollListener listener) {
-        mRecView.removeOnScrollListener(listener);
-    }
-
-    @Override
-    public Point createAbsolutePoint(Point relativePoint) {
-        return new Point(relativePoint.x + mRecView.computeHorizontalScrollOffset(),
-                relativePoint.y + mRecView.computeVerticalScrollOffset());
-    }
-
-    @Override
-    public Rect getAbsoluteRectForChildViewAt(int index) {
-        final View child = mRecView.getChildAt(index);
-        final Rect childRect = new Rect();
-        child.getHitRect(childRect);
-        childRect.left += mRecView.computeHorizontalScrollOffset();
-        childRect.right += mRecView.computeHorizontalScrollOffset();
-        childRect.top += mRecView.computeVerticalScrollOffset();
-        childRect.bottom += mRecView.computeVerticalScrollOffset();
-        return childRect;
-    }
-
-    @Override
-    public int getChildCount() {
-        return mRecView.getAdapter().getItemCount();
-    }
-
-    @Override
-    public int getVisibleChildCount() {
-        return mRecView.getChildCount();
-    }
-
-    @Override
-    public int getColumnCount() {
-        RecyclerView.LayoutManager layoutManager = mRecView.getLayoutManager();
-        if (layoutManager instanceof GridLayoutManager) {
-            return ((GridLayoutManager) layoutManager).getSpanCount();
-        }
-
-        // Otherwise, it is a list with 1 column.
-        return 1;
-    }
-
-    @Override
-    public int getHeight() {
-        return mRecView.getHeight();
-    }
-
-    @Override
-    public void invalidateView() {
-        mRecView.invalidate();
-    }
-
-    @Override
-    public void runAtNextFrame(Runnable r) {
-        mRecView.postOnAnimation(r);
-    }
-
-    @Override
-    public void removeCallback(Runnable r) {
-        mRecView.removeCallbacks(r);
-    }
-
-    @Override
-    public void scrollBy(int dy) {
-        mRecView.scrollBy(0, dy);
-    }
-
-    @Override
-    public void showBand(Rect rect) {
-        mBand.setBounds(rect);
-
-        if (!mIsOverlayShown) {
-            mRecView.getOverlay().add(mBand);
-        }
-    }
-
-    @Override
-    public void hideBand() {
-        mRecView.getOverlay().remove(mBand);
-    }
-
-    @Override
-    public boolean hasView(int pos) {
-        return mRecView.findViewHolderForAdapterPosition(pos) != null;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/DefaultBandPredicate.java b/src/com/android/documentsui/selection/DefaultBandPredicate.java
deleted file mode 100644
index 5de59d8..0000000
--- a/src/com/android/documentsui/selection/DefaultBandPredicate.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.support.annotation.Nullable;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-
-/**
- * BandPredicate that consults ItemDetails, premitting band selection to start
- * when the event is not in the drag region of the item.
- */
-public final class DefaultBandPredicate extends BandPredicate {
-
-    private final ItemDetailsLookup mDetailsLookup;
-
-    public DefaultBandPredicate(ItemDetailsLookup detailsLookup) {
-        checkArgument(detailsLookup != null);
-
-        mDetailsLookup = detailsLookup;
-    }
-
-    @Override
-    public boolean canInitiate(MotionEvent e) {
-        @Nullable ItemDetails details = mDetailsLookup.getItemDetails(e);
-        return (details != null)
-            ? !details.inDragRegion(e)
-            : true;
-    }
-}
diff --git a/src/com/android/documentsui/selection/DefaultSelectionHelper.java b/src/com/android/documentsui/selection/DefaultSelectionHelper.java
deleted file mode 100644
index 75fcacb..0000000
--- a/src/com/android/documentsui/selection/DefaultSelectionHelper.java
+++ /dev/null
@@ -1,554 +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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-import static android.support.v4.util.Preconditions.checkState;
-import static com.android.documentsui.selection.Shared.DEBUG;
-import static com.android.documentsui.selection.Shared.TAG;
-
-import android.support.annotation.IntDef;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.Adapter;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * {@link SelectionHelper} providing support traditional multi-item selection on top
- * of {@link RecyclerView}.
- *
- * <p>The class supports running in a single-select mode, which can be enabled
- * by passing {@colde #MODE_SINGLE} to the constructor.
- */
-public final class DefaultSelectionHelper extends SelectionHelper {
-
-    public static final int MODE_MULTIPLE = 0;
-    public static final int MODE_SINGLE = 1;
-
-    @IntDef(flag = true, value = {
-            MODE_MULTIPLE,
-            MODE_SINGLE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SelectionMode {}
-
-    private static final int RANGE_REGULAR = 0;
-
-    /**
-     * "Provisional" selection represents a overlay on the primary selection. A provisional
-     * selection maybe be eventually added to the primary selection, or it may be abandoned.
-     *
-     * <p>E.g. BandController creates a provisional selection while a user is actively selecting
-     * items with the band. Provisionally selected items are considered to be selected in
-     * {@link Selection#contains(String)} and related methods. A provisional may be abandoned or
-     * applied by selection components (like
-     * {@link com.android.documentsui.selection.BandSelectionHelper}).
-     *
-     * <p>A provisional selection may intersect the primary selection, however clearing the
-     * provisional selection will not affect the primary selection where the two may intersect.
-     */
-    private static final int RANGE_PROVISIONAL = 1;
-    @IntDef({
-        RANGE_REGULAR,
-        RANGE_PROVISIONAL
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    @interface RangeType {}
-
-    private final Selection mSelection = new Selection();
-    private final List<SelectionObserver> mObservers = new ArrayList<>(1);
-    private final RecyclerView.Adapter<?> mAdapter;
-    private final StableIdProvider mStableIds;
-    private final SelectionPredicate mSelectionPredicate;
-    private final RecyclerView.AdapterDataObserver mAdapterObserver;
-    private final RangeCallbacks mRangeCallbacks;
-    private final boolean mSingleSelect;
-
-    private @Nullable Range mRange;
-
-    /**
-     * Creates a new instance.
-     *
-     * @param mode single or multiple selection mode. In single selection mode
-     *     users can only select a single item.
-     * @param adapter {@link Adapter} for the RecyclerView this instance is coupled with.
-     * @param stableIds client supplied class providing access to stable ids.
-     * @param selectionPredicate A predicate allowing the client to disallow selection
-     *     of individual elements.
-     */
-    public DefaultSelectionHelper(
-            @SelectionMode int mode,
-            RecyclerView.Adapter<?> adapter,
-            StableIdProvider stableIds,
-            SelectionPredicate selectionPredicate) {
-
-        checkArgument(mode == MODE_SINGLE || mode == MODE_MULTIPLE);
-        checkArgument(adapter != null);
-        checkArgument(stableIds != null);
-        checkArgument(selectionPredicate != null);
-
-        mAdapter = adapter;
-        mStableIds = stableIds;
-        mSelectionPredicate = selectionPredicate;
-        mAdapterObserver = new AdapterObserver();
-        mRangeCallbacks = new RangeCallbacks();
-
-        mSingleSelect = mode == MODE_SINGLE;
-
-        mAdapter.registerAdapterDataObserver(mAdapterObserver);
-    }
-
-    @Override
-    public void addObserver(SelectionObserver callback) {
-        checkArgument(callback != null);
-        mObservers.add(callback);
-    }
-
-    @Override
-    public boolean hasSelection() {
-        return !mSelection.isEmpty();
-    }
-
-    @Override
-    public Selection getSelection() {
-        return mSelection;
-    }
-
-    @Override
-    public void copySelection(Selection dest) {
-        dest.copyFrom(mSelection);
-    }
-
-    @Override
-    public boolean isSelected(String id) {
-        return mSelection.contains(id);
-    }
-
-    @Override
-    public void restoreSelection(Selection other) {
-        setItemsSelectedQuietly(other.mSelection, true);
-        // NOTE: We intentionally don't restore provisional selection. It's provisional.
-        notifySelectionRestored();
-    }
-
-    @Override
-    public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
-        boolean changed = setItemsSelectedQuietly(ids, selected);
-        notifySelectionChanged();
-        return changed;
-    }
-
-    private boolean setItemsSelectedQuietly(Iterable<String> ids, boolean selected) {
-        boolean changed = false;
-        for (String id: ids) {
-            boolean itemChanged = selected
-                    ? canSetState(id, true) && mSelection.add(id)
-                    : canSetState(id, false) && mSelection.remove(id);
-            if (itemChanged) {
-                notifyItemStateChanged(id, selected);
-            }
-            changed |= itemChanged;
-        }
-        return changed;
-    }
-
-    @Override
-    public void clearSelection() {
-        if (!hasSelection()) {
-            return;
-        }
-
-        Selection prev = clearSelectionQuietly();
-        notifySelectionCleared(prev);
-        notifySelectionChanged();
-    }
-
-    /**
-     * Clears the selection, without notifying selection listeners.
-     * Returns items in previous selection. Callers are responsible for notifying
-     * listeners about changes.
-     */
-    private Selection clearSelectionQuietly() {
-        mRange = null;
-
-        Selection prevSelection = new Selection();
-        if (hasSelection()) {
-            copySelection(prevSelection);
-            mSelection.clear();
-        }
-
-        return prevSelection;
-    }
-
-    @Override
-    public boolean select(String id) {
-        checkArgument(id != null);
-
-        if (!mSelection.contains(id)) {
-            if (!canSetState(id, true)) {
-                if (DEBUG) Log.d(TAG, "Select cancelled by selection predicate test.");
-                return false;
-            }
-
-            // Enforce single selection policy.
-            if (mSingleSelect && hasSelection()) {
-                Selection prev = clearSelectionQuietly();
-                notifySelectionCleared(prev);
-            }
-
-            mSelection.add(id);
-            notifyItemStateChanged(id, true);
-            notifySelectionChanged();
-
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean deselect(String id) {
-        checkArgument(id != null);
-
-        if (mSelection.contains(id)) {
-            if (!canSetState(id, false)) {
-                if (DEBUG) Log.d(TAG, "Deselect cancelled by selection predicate test.");
-                return false;
-            }
-            mSelection.remove(id);
-            notifyItemStateChanged(id, false);
-            notifySelectionChanged();
-            if (mSelection.isEmpty() && isRangeActive()) {
-                // if there's nothing in the selection and there is an active ranger it results
-                // in unexpected behavior when the user tries to start range selection: the item
-                // which the ranger 'thinks' is the already selected anchor becomes unselectable
-                endRange();
-            }
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public void startRange(int pos) {
-        select(mStableIds.getStableId(pos));
-        anchorRange(pos);
-    }
-
-    @Override
-    public void extendRange(int pos) {
-        extendRange(pos, RANGE_REGULAR);
-    }
-
-    @Override
-    public void endRange() {
-        mRange = null;
-        // Clean up in case there was any leftover provisional selection
-        clearProvisionalSelection();
-    }
-
-    @Override
-    public void anchorRange(int position) {
-        checkArgument(position != RecyclerView.NO_POSITION);
-
-        // TODO: I'm not a fan of silently ignoring calls.
-        // Determine if there are any cases where method can be called
-        // w/o item already being selected. Else, tighten up the ship
-        // and make this conditional guard into a proper precondition check.
-        if (mSelection.contains(mStableIds.getStableId(position))) {
-            mRange = new Range(mRangeCallbacks, position);
-        }
-    }
-
-    @Override
-    public void extendProvisionalRange(int pos) {
-        extendRange(pos, RANGE_PROVISIONAL);
-    }
-
-    /**
-     * Sets the end point for the current range selection, started by a call to
-     * {@link #startRange(int)}. This function should only be called when a range selection
-     * is active (see {@link #isRangeActive()}. Items in the range [anchor, end] will be
-     * selected or in provisional select, depending on the type supplied. Note that if the type is
-     * provisional selection, one should do {@link #mergeProvisionalSelection()} at some
-     * point before calling on {@link #endRange()}.
-     *
-     * @param pos The new end position for the selection range.
-     * @param type The type of selection the range should utilize.
-     */
-    private void extendRange(int pos, @RangeType int type) {
-        checkState(isRangeActive(), "Range start point not set.");
-
-        mRange.extendSelection(pos, type);
-
-        // We're being lazy here notifying even when something might not have changed.
-        // To make this more correct, we'd need to update the Ranger class to return
-        // information about what has changed.
-        notifySelectionChanged();
-    }
-
-    @Override
-    public void setProvisionalSelection(Set<String> newSelection) {
-        Map<String, Boolean> delta = mSelection.setProvisionalSelection(newSelection);
-        for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
-            notifyItemStateChanged(entry.getKey(), entry.getValue());
-        }
-
-        notifySelectionChanged();
-    }
-
-    @Override
-    public void mergeProvisionalSelection() {
-        mSelection.mergeProvisionalSelection();
-    }
-
-    @Override
-    public void clearProvisionalSelection() {
-        for (String id : mSelection.mProvisionalSelection) {
-            notifyItemStateChanged(id, false);
-        }
-        mSelection.clearProvisionalSelection();
-    }
-
-    @Override
-    public boolean isRangeActive() {
-        return mRange != null;
-    }
-
-    private boolean canSetState(String id, boolean nextState) {
-        return mSelectionPredicate.canSetStateForId(id, nextState);
-    }
-
-    private void onDataSetChanged() {
-        // Update the selection to remove any disappeared IDs.
-        mSelection.clearProvisionalSelection();
-        mSelection.intersect(mStableIds.getStableIds());
-        notifySelectionReset();
-
-        for (String id : mSelection) {
-            // If the underlying data set has changed, before restoring
-            // selection we must re-verify that it can be selected.
-            // Why? Because if the dataset has changed, then maybe the
-            // selectability of an item has changed.
-            if (!canSetState(id, true)) {
-                deselect(id);
-            } else {
-                int lastListener = mObservers.size() - 1;
-                for (int i = lastListener; i >= 0; i--) {
-                    mObservers.get(i).onItemStateChanged(id, true);
-                }
-            }
-        }
-        notifySelectionChanged();
-    }
-
-    private void onDataSetItemRangeInserted(int startPosition, int itemCount) {
-        mSelection.clearProvisionalSelection();
-    }
-
-    private void onDataSetItemRangeRemoved(int startPosition, int itemCount) {
-        checkArgument(startPosition >= 0);
-        checkArgument(itemCount > 0);
-
-        mSelection.clearProvisionalSelection();
-
-        // Remove any disappeared IDs from the selection.
-        //
-        // Ideally there could be a cheaper approach, checking
-        // each position individually, but since the source of
-        // truth for stable ids (StableIdProvider) probably
-        // it-self no-longer knows about the positions in question
-        // we fall back to the sledge hammer approach.
-        mSelection.intersect(mStableIds.getStableIds());
-    }
-
-    /**
-     * Notifies registered listeners when the selection status of a single item
-     * (identified by {@code position}) changes.
-     */
-    private void notifyItemStateChanged(String id, boolean selected) {
-        checkArgument(id != null);
-
-        int lastListenerIndex = mObservers.size() - 1;
-        for (int i = lastListenerIndex; i >= 0; i--) {
-            mObservers.get(i).onItemStateChanged(id, selected);
-        }
-
-        int position = mStableIds.getPosition(id);
-        if (DEBUG) Log.d(TAG, "ITEM " + id + " CHANGED at pos: " + position);
-
-        if (position >= 0) {
-            mAdapter.notifyItemChanged(position, SelectionHelper.SELECTION_CHANGED_MARKER);
-        } else {
-            Log.w(TAG, "Item change notification received for unknown item: " + id);
-        }
-    }
-
-    private void notifySelectionCleared(Selection selection) {
-        for (String id: selection.mSelection) {
-            notifyItemStateChanged(id, false);
-        }
-        for (String id: selection.mProvisionalSelection) {
-            notifyItemStateChanged(id, false);
-        }
-    }
-
-    /**
-     * Notifies registered listeners when the selection has changed. This
-     * notification should be sent only once a full series of changes
-     * is complete, e.g. clearingSelection, or updating the single
-     * selection from one item to another.
-     */
-    private void notifySelectionChanged() {
-        int lastListenerIndex = mObservers.size() - 1;
-        for (int i = lastListenerIndex; i >= 0; i--) {
-            mObservers.get(i).onSelectionChanged();
-        }
-    }
-
-    private void notifySelectionRestored() {
-        int lastListenerIndex = mObservers.size() - 1;
-        for (int i = lastListenerIndex; i >= 0; i--) {
-            mObservers.get(i).onSelectionRestored();
-        }
-    }
-
-    private void notifySelectionReset() {
-        int lastListenerIndex = mObservers.size() - 1;
-        for (int i = lastListenerIndex; i >= 0; i--) {
-            mObservers.get(i).onSelectionReset();
-        }
-    }
-
-    private void updateForRange(int begin, int end, boolean selected, @RangeType int type) {
-        switch (type) {
-            case RANGE_REGULAR:
-                updateForRegularRange(begin, end, selected);
-                break;
-            case RANGE_PROVISIONAL:
-                updateForProvisionalRange(begin, end, selected);
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid range type: " + type);
-        }
-    }
-
-    private void updateForRegularRange(int begin, int end, boolean selected) {
-        checkArgument(end >= begin);
-
-        for (int i = begin; i <= end; i++) {
-            String id = mStableIds.getStableId(i);
-            if (id == null) {
-                continue;
-            }
-
-            if (selected) {
-                select(id);
-            } else {
-                deselect(id);
-            }
-        }
-    }
-
-    private void updateForProvisionalRange(int begin, int end, boolean selected) {
-        checkArgument(end >= begin);
-
-        for (int i = begin; i <= end; i++) {
-            String id = mStableIds.getStableId(i);
-            if (id == null) {
-                continue;
-            }
-
-            boolean changedState = false;
-            if (selected) {
-                boolean canSelect = canSetState(id, true);
-                if (canSelect && !mSelection.mSelection.contains(id)) {
-                    mSelection.mProvisionalSelection.add(id);
-                    changedState = true;
-                }
-            } else {
-                mSelection.mProvisionalSelection.remove(id);
-                changedState = true;
-            }
-
-            // Only notify item callbacks when something's state is actually changed in provisional
-            // selection.
-            if (changedState) {
-                notifyItemStateChanged(id, selected);
-            }
-        }
-
-        notifySelectionChanged();
-    }
-
-    private final class AdapterObserver extends RecyclerView.AdapterDataObserver {
-        @Override
-        public void onChanged() {
-            onDataSetChanged();
-        }
-
-        @Override
-        public void onItemRangeChanged(
-                int startPosition, int itemCount, Object payload) {
-            // No change in position. Ignore, since we assume
-            // selection is a user driven activity. So changes
-            // in properties of items shouldn't result in a
-            // change of selection.
-        }
-
-        @Override
-        public void onItemRangeInserted(int startPosition, int itemCount) {
-            onDataSetItemRangeInserted(startPosition, itemCount);
-        }
-
-        @Override
-        public void onItemRangeRemoved(int startPosition, int itemCount) {
-            onDataSetItemRangeRemoved(startPosition, itemCount);
-        }
-
-        @Override
-        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    private final class RangeCallbacks extends Range.Callbacks {
-        @Override
-        void updateForRange(int begin, int end, boolean selected, int type) {
-            switch (type) {
-                case RANGE_REGULAR:
-                    updateForRegularRange(begin, end, selected);
-                    break;
-                case RANGE_PROVISIONAL:
-                    updateForProvisionalRange(begin, end, selected);
-                    break;
-                default:
-                    throw new IllegalArgumentException(
-                            "Invalid range type: " + type);
-            }
-        }
-    }
-}
diff --git a/src/com/android/documentsui/selection/GestureRouter.java b/src/com/android/documentsui/selection/GestureRouter.java
deleted file mode 100644
index b336450..0000000
--- a/src/com/android/documentsui/selection/GestureRouter.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkNotNull;
-
-import android.support.annotation.Nullable;
-import android.view.GestureDetector.OnDoubleTapListener;
-import android.view.GestureDetector.OnGestureListener;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.MotionEvent;
-
-/**
- * GestureRouter is responsible for routing gestures detected by a GestureDetector
- * to registered handlers. The primary function is to divide events by tool-type
- * allowing handlers to cleanly implement tool-type specific policies.
- */
-public final class GestureRouter<T extends OnGestureListener & OnDoubleTapListener>
-        implements OnGestureListener, OnDoubleTapListener {
-
-    private final ToolHandlerRegistry<T> mDelegates;
-
-    public GestureRouter(T defaultDelegate) {
-        checkNotNull(defaultDelegate);
-        mDelegates = new ToolHandlerRegistry<>(defaultDelegate);
-    }
-
-    public GestureRouter() {
-        this((T) new SimpleOnGestureListener());
-    }
-
-    /**
-     * @param toolType
-     * @param delegate the delegate, or null to unregister.
-     */
-    public void register(int toolType, @Nullable T delegate) {
-        mDelegates.set(toolType, delegate);
-    }
-
-    @Override
-    public boolean onSingleTapConfirmed(MotionEvent e) {
-        return mDelegates.get(e).onSingleTapConfirmed(e);
-    }
-
-    @Override
-    public boolean onDoubleTap(MotionEvent e) {
-        return mDelegates.get(e).onDoubleTap(e);
-    }
-
-    @Override
-    public boolean onDoubleTapEvent(MotionEvent e) {
-        return mDelegates.get(e).onDoubleTapEvent(e);
-    }
-
-    @Override
-    public boolean onDown(MotionEvent e) {
-        return mDelegates.get(e).onDown(e);
-    }
-
-    @Override
-    public void onShowPress(MotionEvent e) {
-        mDelegates.get(e).onShowPress(e);
-    }
-
-    @Override
-    public boolean onSingleTapUp(MotionEvent e) {
-        return mDelegates.get(e).onSingleTapUp(e);
-    }
-
-    @Override
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-        return mDelegates.get(e2).onScroll(e1, e2, distanceX, distanceY);
-    }
-
-    @Override
-    public void onLongPress(MotionEvent e) {
-        mDelegates.get(e).onLongPress(e);
-    }
-
-    @Override
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-        return mDelegates.get(e2).onFling(e1, e2, velocityX, velocityY);
-    }
-}
diff --git a/src/com/android/documentsui/selection/GestureSelectionHelper.java b/src/com/android/documentsui/selection/GestureSelectionHelper.java
deleted file mode 100644
index 8a55cc3..0000000
--- a/src/com/android/documentsui/selection/GestureSelectionHelper.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-import static android.support.v4.util.Preconditions.checkState;
-
-import android.graphics.Point;
-import android.os.Build;
-import android.support.annotation.NonNull;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
-
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
-
-/**
- * GestureSelectionHelper provides logic that interprets a combination
- * of motions and gestures in order to provide gesture driven selection support
- * when used in conjunction with RecyclerView and other classes in the ReyclerView
- * selection support package.
- */
-public final class GestureSelectionHelper extends ScrollHost implements OnItemTouchListener {
-
-    private static final String TAG = "GestureSelectionHelper";
-
-    private final SelectionHelper mSelectionMgr;
-    private final Runnable mScroller;
-    private final ViewDelegate mView;
-    private final ContentLock mLock;
-    private final ItemDetailsLookup mItemLookup;
-
-    private int mLastTouchedItemPosition = RecyclerView.NO_POSITION;
-    private boolean mStarted = false;
-    private Point mLastInterceptedPoint;
-
-    /**
-     * See {@link #create(SelectionHelper, RecyclerView, ContentLock)} for convenience
-     * method.
-     */
-    @VisibleForTesting
-    GestureSelectionHelper(
-            SelectionHelper selectionHelper,
-            ViewDelegate view,
-            ContentLock lock,
-            ItemDetailsLookup itemLookup) {
-
-        checkArgument(selectionHelper != null);
-        checkArgument(view != null);
-        checkArgument(lock != null);
-        checkArgument(itemLookup != null);
-
-        mSelectionMgr = selectionHelper;
-        mView = view;
-        mLock = lock;
-        mItemLookup = itemLookup;
-
-        mScroller = new ViewAutoScroller(this, mView);
-    }
-
-    /**
-     * Explicitly kicks off a gesture multi-select.
-     *
-     * @return true if started.
-     */
-    public void start() {
-        checkState(!mStarted);
-        // See: b/70518185. It appears start() is being called via onLongPress
-        // even though we never received an intial handleInterceptedDownEvent
-        // where we would usually initialize mLastStartedItemPos.
-        if (mLastTouchedItemPosition == RecyclerView.NO_POSITION) {
-            Log.w(TAG, "Illegal state. Can't start without valid mLastStartedItemPos.");
-            return;
-        }
-
-        // Partner code in MotionInputHandler ensures items
-        // are selected and range established prior to
-        // start being called.
-        // Verify the truth of that statement here
-        // to make the implicit coupling less of a time bomb.
-        checkState(mSelectionMgr.isRangeActive());
-
-        mLock.checkUnlocked();
-
-        mStarted = true;
-        mLock.block();
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(RecyclerView unused, MotionEvent e) {
-        if (MotionEvents.isMouseEvent(e)) {
-            if (Shared.DEBUG) Log.w(TAG, "Unexpected Mouse event. Check configuration.");
-        }
-
-        // TODO(b/109808552): It seems that mLastStartedItemPos should likely be set as a method
-        // parameter in start().
-        if (e.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            if (mItemLookup.getItemDetails(e) != null) {
-                mLastTouchedItemPosition = mView.getItemUnder(e);
-            }
-        }
-
-        // See handleTouch(MotionEvent) javadoc for explanation as to why this is correct.
-        return handleTouch(e);
-    }
-
-    @Override
-    /** @hide */
-    public void onTouchEvent(@NonNull RecyclerView unused, @NonNull MotionEvent e) {
-        // See handleTouch(MotionEvent) javadoc for explanation as to why this is correct.
-        handleTouch(e);
-    }
-
-    /**
-     * If selection has started, will handle all appropriate types of MotionEvents and will return
-     * true if this OnItemTouchListener should start intercepting the rest of the MotionEvents.
-     *
-     * <p>This code, and the fact that this method is used by both OnInterceptTouchEvent and
-     * OnTouchEvent, is correct and valid because:
-     * <ol>
-     * <li>MotionEvents that aren't ACTION_DOWN are only ever passed to either onInterceptTouchEvent
-     * or onTouchEvent; never to both.  The MotionEvents we are handling in this method are not
-     * ACTION_DOWN, and therefore, its appropriate that both the onInterceptTouchEvent and
-     * onTouchEvent code paths cross this method.
-     * <li>This method returns true when we want to intercept MotionEvents.  OnInterceptTouchEvent
-     * uses that information to determine its own return, and OnMotionEvent doesn't have a return
-     * so this methods return value is irrelevant to it.
-     * </ol>
-     */
-    private boolean handleTouch(MotionEvent e) {
-        if (!mStarted) {
-            return false;
-        }
-
-        switch (e.getActionMasked()) {
-            case MotionEvent.ACTION_MOVE:
-                handleMoveEvent(e);
-                return true;
-            case MotionEvent.ACTION_UP:
-                handleUpEvent();
-                return true;
-            case MotionEvent.ACTION_CANCEL:
-                handleCancelEvent();
-                return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-    }
-
-    // Called when ACTION_UP event is to be handled.
-    // Essentially, since this means all gesture movement is over, reset everything and apply
-    // provisional selection.
-    private void handleUpEvent() {
-        mSelectionMgr.mergeProvisionalSelection();
-        endSelection();
-        if (mLastTouchedItemPosition != RecyclerView.NO_POSITION) {
-            mSelectionMgr.startRange(mLastTouchedItemPosition);
-        }
-    }
-
-    // Called when ACTION_CANCEL event is to be handled.
-    // This means this gesture selection is aborted, so reset everything and abandon provisional
-    // selection.
-    private void handleCancelEvent() {
-        mSelectionMgr.clearProvisionalSelection();
-        endSelection();
-    }
-
-    private void endSelection() {
-        checkState(mStarted);
-
-        mLastTouchedItemPosition = RecyclerView.NO_POSITION;
-        mStarted = false;
-        mLock.unblock();
-    }
-
-    // Call when an intercepted ACTION_MOVE event is passed down.
-    // At this point, we are sure user wants to gesture multi-select.
-    private void handleMoveEvent(MotionEvent e) {
-        mLastInterceptedPoint = MotionEvents.getOrigin(e);
-
-        int lastGlidedItemPos = mView.getLastGlidedItemPosition(e);
-        if (lastGlidedItemPos != RecyclerView.NO_POSITION) {
-            doGestureMultiSelect(lastGlidedItemPos);
-        }
-        scrollIfNecessary();
-    }
-
-    // It's possible for events to go over the top/bottom of the RecyclerView.
-    // We want to get a Y-coordinate within the RecyclerView so we can find the childView underneath
-    // correctly.
-    private static float getInboundY(float max, float y) {
-        if (y < 0f) {
-            return 0f;
-        } else if (y > max) {
-            return max;
-        }
-        return y;
-    }
-
-    /* Given the end position, select everything in-between.
-     * @param endPos  The adapter position of the end item.
-     */
-    private void doGestureMultiSelect(int endPos) {
-        mSelectionMgr.extendProvisionalRange(endPos);
-    }
-
-    private void scrollIfNecessary() {
-        mScroller.run();
-    }
-
-    @Override
-    public Point getCurrentPosition() {
-        return mLastInterceptedPoint;
-    }
-
-    @Override
-    public int getViewHeight() {
-        return mView.getHeight();
-    }
-
-    @Override
-    public boolean isActive() {
-        return mStarted && mSelectionMgr.hasSelection();
-    }
-
-    /**
-     * Returns a new instance of GestureSelectionHelper, wrapping the
-     * RecyclerView in a test friendly wrapper.
-     */
-    public static GestureSelectionHelper create(
-            SelectionHelper selectionMgr,
-            RecyclerView recycler,
-            ContentLock lock,
-            ItemDetailsLookup itemLookup) {
-
-        return new GestureSelectionHelper(
-                selectionMgr, new RecyclerViewDelegate(recycler), lock, itemLookup);
-    }
-
-    @VisibleForTesting
-    static abstract class ViewDelegate extends ScrollerCallbacks {
-        abstract int getHeight();
-
-        abstract int getItemUnder(MotionEvent e);
-
-        abstract int getLastGlidedItemPosition(MotionEvent e);
-    }
-
-    @VisibleForTesting
-    static final class RecyclerViewDelegate extends ViewDelegate {
-
-        private final RecyclerView mView;
-
-        RecyclerViewDelegate(RecyclerView view) {
-            checkArgument(view != null);
-            mView = view;
-        }
-
-        @Override
-        int getHeight() {
-            return mView.getHeight();
-        }
-
-        @Override
-        int getItemUnder(MotionEvent e) {
-            View child = mView.findChildViewUnder(e.getX(), e.getY());
-            return child != null
-                    ? mView.getChildAdapterPosition(child)
-                    : RecyclerView.NO_POSITION;
-        }
-
-        @Override
-        int getLastGlidedItemPosition(MotionEvent e) {
-            // If user has moved his pointer to the bottom-right empty pane (ie. to the right of the
-            // last item of the recycler view), we would want to set that as the currentItemPos
-            View lastItem = mView.getLayoutManager()
-                    .getChildAt(mView.getLayoutManager().getChildCount() - 1);
-            int direction =
-                    mView.getContext().getResources().getConfiguration().getLayoutDirection();
-            final boolean pastLastItem = isPastLastItem(lastItem.getTop(),
-                    lastItem.getLeft(),
-                    lastItem.getRight(),
-                    e,
-                    direction);
-
-            // Since views get attached & detached from RecyclerView,
-            // {@link LayoutManager#getChildCount} can return a different number from the actual
-            // number
-            // of items in the adapter. Using the adapter is the for sure way to get the actual last
-            // item position.
-            final float inboundY = getInboundY(mView.getHeight(), e.getY());
-            return (pastLastItem) ? mView.getAdapter().getItemCount() - 1
-                    : mView.getChildAdapterPosition(mView.findChildViewUnder(e.getX(), inboundY));
-        }
-
-        /*
-         * Check to see if MotionEvent if past a particular item, i.e. to the right or to the bottom
-         * of the item.
-         * For RTL, it would to be to the left or to the bottom of the item.
-         */
-        @VisibleForTesting
-        static boolean isPastLastItem(int top, int left, int right, MotionEvent e, int direction) {
-            if (direction == View.LAYOUT_DIRECTION_LTR) {
-                return e.getX() > right && e.getY() > top;
-            } else {
-                return e.getX() < left && e.getY() > top;
-            }
-        }
-
-        @Override
-        public void scrollBy(int dy) {
-            mView.scrollBy(0, dy);
-        }
-
-        @Override
-        public void runAtNextFrame(Runnable r) {
-            mView.postOnAnimation(r);
-        }
-
-        @Override
-        public void removeCallback(Runnable r) {
-            mView.removeCallbacks(r);
-        }
-    }
-}
diff --git a/src/com/android/documentsui/selection/GridModel.java b/src/com/android/documentsui/selection/GridModel.java
deleted file mode 100644
index dae445d..0000000
--- a/src/com/android/documentsui/selection/GridModel.java
+++ /dev/null
@@ -1,727 +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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnScrollListener;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
-
-import com.android.documentsui.selection.BandSelectionHelper.BandHost;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Provides a band selection item model for views within a RecyclerView. This class queries the
- * RecyclerView to determine where its items are placed; then, once band selection is underway,
- * it alerts listeners of which items are covered by the selections.
- */
-final class GridModel {
-
-    // Magical value indicating that a value has not been previously set. primitive null :)
-    static final int NOT_SET = -1;
-
-    // Enum values used to determine the corner at which the origin is located within the
-    private static final int UPPER = 0x00;
-    private static final int LOWER = 0x01;
-    private static final int LEFT = 0x00;
-    private static final int RIGHT = 0x02;
-    private static final int UPPER_LEFT = UPPER | LEFT;
-    private static final int UPPER_RIGHT = UPPER | RIGHT;
-    private static final int LOWER_LEFT = LOWER | LEFT;
-    private static final int LOWER_RIGHT = LOWER | RIGHT;
-
-    private final BandHost mHost;
-    private final StableIdProvider mStableIds;
-    private final SelectionPredicate mSelectionPredicate;
-
-    private final List<SelectionObserver> mOnSelectionChangedListeners =
-            new ArrayList<>();
-
-    // Map from the x-value of the left side of a SparseBooleanArray of adapter positions, keyed
-    // by their y-offset. For example, if the first column of the view starts at an x-value of 5,
-    // mColumns.get(5) would return an array of positions in that column. Within that array, the
-    // value for key y is the adapter position for the item whose y-offset is y.
-    private final SparseArray<SparseIntArray> mColumns = new SparseArray<>();
-
-    // List of limits along the x-axis (columns).
-    // This list is sorted from furthest left to furthest right.
-    private final List<Limits> mColumnBounds = new ArrayList<>();
-
-    // List of limits along the y-axis (rows). Note that this list only contains items which
-    // have been in the viewport.
-    private final List<Limits> mRowBounds = new ArrayList<>();
-
-    // The adapter positions which have been recorded so far.
-    private final SparseBooleanArray mKnownPositions = new SparseBooleanArray();
-
-    // Array passed to registered OnSelectionChangedListeners. One array is created and reused
-    // throughout the lifetime of the object.
-    private final Set<String> mSelection = new HashSet<>();
-
-    // The current pointer (in absolute positioning from the top of the view).
-    private Point mPointer = null;
-
-    // The bounds of the band selection.
-    private RelativePoint mRelativeOrigin;
-    private RelativePoint mRelativePointer;
-
-    private boolean mIsActive;
-
-    // Tracks where the band select originated from. This is used to determine where selections
-    // should expand from when Shift+click is used.
-    private int mPositionNearestOrigin = NOT_SET;
-
-    private final OnScrollListener mScrollListener;
-
-    GridModel(
-            BandHost host,
-            StableIdProvider stableIds,
-            SelectionPredicate selectionPredicate) {
-
-        mHost = host;
-        mStableIds = stableIds;
-        mSelectionPredicate = selectionPredicate;
-
-        mScrollListener = new OnScrollListener() {
-            @Override
-            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-                GridModel.this.onScrolled(recyclerView, dx, dy);
-            }
-        };
-
-        mHost.addOnScrollListener(mScrollListener);
-    }
-
-    /**
-     * Stops listening to the view's scrolls. Call this function before discarding a
-     * GridModel object to prevent memory leaks.
-     */
-    void stopListening() {
-        mHost.removeOnScrollListener(mScrollListener);
-    }
-
-    /**
-     * Start a band select operation at the given point.
-     * @param relativeOrigin The origin of the band select operation, relative to the viewport.
-     *     For example, if the view is scrolled to the bottom, the top-left of the viewport
-     *     would have a relative origin of (0, 0), even though its absolute point has a higher
-     *     y-value.
-     */
-    void startCapturing(Point relativeOrigin) {
-        recordVisibleChildren();
-        if (isEmpty()) {
-            // The selection band logic works only if there is at least one visible child.
-            return;
-        }
-
-        mIsActive = true;
-        mPointer = mHost.createAbsolutePoint(relativeOrigin);
-        mRelativeOrigin = new RelativePoint(mPointer);
-        mRelativePointer = new RelativePoint(mPointer);
-        computeCurrentSelection();
-        notifySelectionChanged();
-    }
-
-    /**
-     * Ends the band selection.
-     */
-    void stopCapturing() {
-        mIsActive = false;
-    }
-
-    /**
-     * Resizes the selection by adjusting the pointer (i.e., the corner of the selection
-     * opposite the origin.
-     * @param relativePointer The pointer (opposite of the origin) of the band select operation,
-     *     relative to the viewport. For example, if the view is scrolled to the bottom, the
-     *     top-left of the viewport would have a relative origin of (0, 0), even though its
-     *     absolute point has a higher y-value.
-     */
-    @VisibleForTesting
-    void resizeSelection(Point relativePointer) {
-        mPointer = mHost.createAbsolutePoint(relativePointer);
-        updateModel();
-    }
-
-    /**
-     * @return The adapter position for the item nearest the origin corresponding to the latest
-     *         band select operation, or NOT_SET if the selection did not cover any items.
-     */
-    int getPositionNearestOrigin() {
-        return mPositionNearestOrigin;
-    }
-
-    private void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-        if (!mIsActive) {
-            return;
-        }
-
-        mPointer.x += dx;
-        mPointer.y += dy;
-        recordVisibleChildren();
-        updateModel();
-    }
-
-    /**
-     * Queries the view for all children and records their location metadata.
-     */
-    private void recordVisibleChildren() {
-        for (int i = 0; i < mHost.getVisibleChildCount(); i++) {
-            int adapterPosition = mHost.getAdapterPositionAt(i);
-            // Sometimes the view is not attached, as we notify the multi selection manager
-            // synchronously, while views are attached asynchronously. As a result items which
-            // are in the adapter may not actually have a corresponding view (yet).
-            if (mHost.hasView(adapterPosition) &&
-                    mSelectionPredicate.canSetStateAtPosition(adapterPosition, true) &&
-                    !mKnownPositions.get(adapterPosition)) {
-                mKnownPositions.put(adapterPosition, true);
-                recordItemData(mHost.getAbsoluteRectForChildViewAt(i), adapterPosition);
-            }
-        }
-    }
-
-    /**
-     * Checks if there are any recorded children.
-     */
-    private boolean isEmpty() {
-        return mColumnBounds.size() == 0 || mRowBounds.size() == 0;
-    }
-
-    /**
-     * Updates the limits lists and column map with the given item metadata.
-     * @param absoluteChildRect The absolute rectangle for the child view being processed.
-     * @param adapterPosition The position of the child view being processed.
-     */
-    private void recordItemData(Rect absoluteChildRect, int adapterPosition) {
-        if (mColumnBounds.size() != mHost.getColumnCount()) {
-            // If not all x-limits have been recorded, record this one.
-            recordLimits(
-                    mColumnBounds, new Limits(absoluteChildRect.left, absoluteChildRect.right));
-        }
-
-        recordLimits(mRowBounds, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
-
-        SparseIntArray columnList = mColumns.get(absoluteChildRect.left);
-        if (columnList == null) {
-            columnList = new SparseIntArray();
-            mColumns.put(absoluteChildRect.left, columnList);
-        }
-        columnList.put(absoluteChildRect.top, adapterPosition);
-    }
-
-    /**
-     * Ensures limits exists within the sorted list limitsList, and adds it to the list if it
-     * does not exist.
-     */
-    private void recordLimits(List<Limits> limitsList, Limits limits) {
-        int index = Collections.binarySearch(limitsList, limits);
-        if (index < 0) {
-            limitsList.add(~index, limits);
-        }
-    }
-
-    /**
-     * Handles a moved pointer; this function determines whether the pointer movement resulted
-     * in a selection change and, if it has, notifies listeners of this change.
-     */
-    private void updateModel() {
-        RelativePoint old = mRelativePointer;
-        mRelativePointer = new RelativePoint(mPointer);
-        if (old != null && mRelativePointer.equals(old)) {
-            return;
-        }
-
-        computeCurrentSelection();
-        notifySelectionChanged();
-    }
-
-    /**
-     * Computes the currently-selected items.
-     */
-    private void computeCurrentSelection() {
-        if (areItemsCoveredByBand(mRelativePointer, mRelativeOrigin)) {
-            updateSelection(computeBounds());
-        } else {
-            mSelection.clear();
-            mPositionNearestOrigin = NOT_SET;
-        }
-    }
-
-    /**
-     * Notifies all listeners of a selection change. Note that this function simply passes
-     * mSelection, so computeCurrentSelection() should be called before this
-     * function.
-     */
-    private void notifySelectionChanged() {
-        for (SelectionObserver listener : mOnSelectionChangedListeners) {
-            listener.onSelectionChanged(mSelection);
-        }
-    }
-
-    /**
-     * @param rect Rectangle including all covered items.
-     */
-    private void updateSelection(Rect rect) {
-        int columnStart =
-                Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
-
-        checkArgument(columnStart >= 0, "Rect doesn't intesect any known column.");
-
-        int columnEnd = columnStart;
-
-        for (int i = columnStart; i < mColumnBounds.size()
-                && mColumnBounds.get(i).lowerLimit <= rect.right; i++) {
-            columnEnd = i;
-        }
-
-        int rowStart = Collections.binarySearch(mRowBounds, new Limits(rect.top, rect.top));
-        if (rowStart < 0) {
-            mPositionNearestOrigin = NOT_SET;
-            return;
-        }
-
-        int rowEnd = rowStart;
-        for (int i = rowStart; i < mRowBounds.size()
-                && mRowBounds.get(i).lowerLimit <= rect.bottom; i++) {
-            rowEnd = i;
-        }
-
-        updateSelection(columnStart, columnEnd, rowStart, rowEnd);
-    }
-
-    /**
-     * Computes the selection given the previously-computed start- and end-indices for each
-     * row and column.
-     */
-    private void updateSelection(
-            int columnStartIndex, int columnEndIndex, int rowStartIndex, int rowEndIndex) {
-
-        if (BandSelectionHelper.DEBUG) {
-            Log.d(BandSelectionHelper.TAG, String.format(
-                    "updateSelection: %d, %d, %d, %d",
-                    columnStartIndex, columnEndIndex, rowStartIndex, rowEndIndex));
-        }
-
-        mSelection.clear();
-        for (int column = columnStartIndex; column <= columnEndIndex; column++) {
-            SparseIntArray items = mColumns.get(mColumnBounds.get(column).lowerLimit);
-            for (int row = rowStartIndex; row <= rowEndIndex; row++) {
-                // The default return value for SparseIntArray.get is 0, which is a valid
-                // position. Use a sentry value to prevent erroneously selecting item 0.
-                final int rowKey = mRowBounds.get(row).lowerLimit;
-                int position = items.get(rowKey, NOT_SET);
-                if (position != NOT_SET) {
-                    String id = mStableIds.getStableId(position);
-                    if (id != null) {
-                        // The adapter inserts items for UI layout purposes that aren't
-                        // associated with files. Those will have a null model ID.
-                        // Don't select them.
-                        if (canSelect(id)) {
-                            mSelection.add(id);
-                        }
-                    }
-                    if (isPossiblePositionNearestOrigin(column, columnStartIndex, columnEndIndex,
-                            row, rowStartIndex, rowEndIndex)) {
-                        // If this is the position nearest the origin, record it now so that it
-                        // can be returned by endSelection() later.
-                        mPositionNearestOrigin = position;
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean canSelect(String id) {
-        return mSelectionPredicate.canSetStateForId(id, true);
-    }
-
-    /**
-     * @return Returns true if the position is the nearest to the origin, or, in the case of the
-     *     lower-right corner, whether it is possible that the position is the nearest to the
-     *     origin. See comment below for reasoning for this special case.
-     */
-    private boolean isPossiblePositionNearestOrigin(int columnIndex, int columnStartIndex,
-            int columnEndIndex, int rowIndex, int rowStartIndex, int rowEndIndex) {
-        int corner = computeCornerNearestOrigin();
-        switch (corner) {
-            case UPPER_LEFT:
-                return columnIndex == columnStartIndex && rowIndex == rowStartIndex;
-            case UPPER_RIGHT:
-                return columnIndex == columnEndIndex && rowIndex == rowStartIndex;
-            case LOWER_LEFT:
-                return columnIndex == columnStartIndex && rowIndex == rowEndIndex;
-            case LOWER_RIGHT:
-                // Note that in some cases, the last row will not have as many items as there
-                // are columns (e.g., if there are 4 items and 3 columns, the second row will
-                // only have one item in the first column). This function is invoked for each
-                // position from left to right, so return true for any position in the bottom
-                // row and only the right-most position in the bottom row will be recorded.
-                return rowIndex == rowEndIndex;
-            default:
-                throw new RuntimeException("Invalid corner type.");
-        }
-    }
-
-    /**
-     * Listener for changes in which items have been band selected.
-     */
-    public static abstract class SelectionObserver {
-        abstract void onSelectionChanged(Set<String> updatedSelection);
-    }
-
-    void addOnSelectionChangedListener(SelectionObserver listener) {
-        mOnSelectionChangedListeners.add(listener);
-    }
-
-    /**
-     * Called when {@link BandSelectionHelper} is finished with a GridModel.
-     */
-    void onDestroy() {
-        mOnSelectionChangedListeners.clear();
-        stopListening();
-    }
-
-    /**
-     * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
-     * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
-     * of item columns and the top- and bottom sides of item rows so that it can be determined
-     * whether the pointer is located within the bounds of an item.
-     */
-    private static class Limits implements Comparable<Limits> {
-        int lowerLimit;
-        int upperLimit;
-
-        Limits(int lowerLimit, int upperLimit) {
-            this.lowerLimit = lowerLimit;
-            this.upperLimit = upperLimit;
-        }
-
-        @Override
-        public int compareTo(Limits other) {
-            return lowerLimit - other.lowerLimit;
-        }
-
-        @Override
-        public int hashCode() {
-            return lowerLimit ^ upperLimit;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof Limits)) {
-                return false;
-            }
-
-            return ((Limits) other).lowerLimit == lowerLimit &&
-                    ((Limits) other).upperLimit == upperLimit;
-        }
-
-        @Override
-        public String toString() {
-            return "(" + lowerLimit + ", " + upperLimit + ")";
-        }
-    }
-
-    /**
-     * The location of a coordinate relative to items. This class represents a general area of the
-     * view as it relates to band selection rather than an explicit point. For example, two
-     * different points within an item are considered to have the same "location" because band
-     * selection originating within the item would select the same items no matter which point
-     * was used. Same goes for points between items as well as those at the very beginning or end
-     * of the view.
-     *
-     * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
-     * advantage of tying the value to the Limits of items along that axis. This allows easy
-     * selection of items within those Limits as opposed to a search through every item to see if a
-     * given coordinate value falls within those Limits.
-     */
-    private static class RelativeCoordinate
-            implements Comparable<RelativeCoordinate> {
-        /**
-         * Location describing points after the last known item.
-         */
-        static final int AFTER_LAST_ITEM = 0;
-
-        /**
-         * Location describing points before the first known item.
-         */
-        static final int BEFORE_FIRST_ITEM = 1;
-
-        /**
-         * Location describing points between two items.
-         */
-        static final int BETWEEN_TWO_ITEMS = 2;
-
-        /**
-         * Location describing points within the limits of one item.
-         */
-        static final int WITHIN_LIMITS = 3;
-
-        /**
-         * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
-         * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
-         */
-        final int type;
-
-        /**
-         * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
-         * BETWEEN_TWO_ITEMS.
-         */
-        Limits limitsBeforeCoordinate;
-
-        /**
-         * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
-         */
-        Limits limitsAfterCoordinate;
-
-        // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
-        Limits mFirstKnownItem;
-        // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
-        Limits mLastKnownItem;
-
-        /**
-         * @param limitsList The sorted limits list for the coordinate type. If this
-         *     CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
-         *     mYLimitsList should be pased.
-         * @param value The coordinate value.
-         */
-        RelativeCoordinate(List<Limits> limitsList, int value) {
-            int index = Collections.binarySearch(limitsList, new Limits(value, value));
-
-            if (index >= 0) {
-                this.type = WITHIN_LIMITS;
-                this.limitsBeforeCoordinate = limitsList.get(index);
-            } else if (~index == 0) {
-                this.type = BEFORE_FIRST_ITEM;
-                this.mFirstKnownItem = limitsList.get(0);
-            } else if (~index == limitsList.size()) {
-                Limits lastLimits = limitsList.get(limitsList.size() - 1);
-                if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
-                    this.type = WITHIN_LIMITS;
-                    this.limitsBeforeCoordinate = lastLimits;
-                } else {
-                    this.type = AFTER_LAST_ITEM;
-                    this.mLastKnownItem = lastLimits;
-                }
-            } else {
-                Limits limitsBeforeIndex = limitsList.get(~index - 1);
-                if (limitsBeforeIndex.lowerLimit <= value
-                        && value <= limitsBeforeIndex.upperLimit) {
-                    this.type = WITHIN_LIMITS;
-                    this.limitsBeforeCoordinate = limitsList.get(~index - 1);
-                } else {
-                    this.type = BETWEEN_TWO_ITEMS;
-                    this.limitsBeforeCoordinate = limitsList.get(~index - 1);
-                    this.limitsAfterCoordinate = limitsList.get(~index);
-                }
-            }
-        }
-
-        int toComparisonValue() {
-            if (type == BEFORE_FIRST_ITEM) {
-                return mFirstKnownItem.lowerLimit - 1;
-            } else if (type == AFTER_LAST_ITEM) {
-                return mLastKnownItem.upperLimit + 1;
-            } else if (type == BETWEEN_TWO_ITEMS) {
-                return limitsBeforeCoordinate.upperLimit + 1;
-            } else {
-                return limitsBeforeCoordinate.lowerLimit;
-            }
-        }
-
-        @Override
-        public int hashCode() {
-            return mFirstKnownItem.lowerLimit
-                    ^ mLastKnownItem.upperLimit
-                    ^ limitsBeforeCoordinate.upperLimit
-                    ^ limitsBeforeCoordinate.lowerLimit;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof RelativeCoordinate)) {
-                return false;
-            }
-
-            RelativeCoordinate otherCoordinate = (RelativeCoordinate) other;
-            return toComparisonValue() == otherCoordinate.toComparisonValue();
-        }
-
-        @Override
-        public int compareTo(RelativeCoordinate other) {
-            return toComparisonValue() - other.toComparisonValue();
-        }
-    }
-
-    /**
-     * The location of a point relative to the Limits of nearby items; consists of both an x- and
-     * y-RelativeCoordinateLocation.
-     */
-    private class RelativePoint {
-        final RelativeCoordinate xLocation;
-        final RelativeCoordinate yLocation;
-
-        RelativePoint(Point point) {
-            this.xLocation = new RelativeCoordinate(mColumnBounds, point.x);
-            this.yLocation = new RelativeCoordinate(mRowBounds, point.y);
-        }
-
-        @Override
-        public int hashCode() {
-            return xLocation.toComparisonValue()
-                    ^ yLocation.toComparisonValue();
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof RelativePoint)) {
-                return false;
-            }
-
-            RelativePoint otherPoint = (RelativePoint) other;
-            return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
-        }
-    }
-
-    /**
-     * Generates a rectangle which contains the items selected by the pointer and origin.
-     * @return The rectangle, or null if no items were selected.
-     */
-    private Rect computeBounds() {
-        Rect rect = new Rect();
-        rect.left = getCoordinateValue(
-                min(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
-                mColumnBounds,
-                true);
-        rect.right = getCoordinateValue(
-                max(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
-                mColumnBounds,
-                false);
-        rect.top = getCoordinateValue(
-                min(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
-                mRowBounds,
-                true);
-        rect.bottom = getCoordinateValue(
-                max(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
-                mRowBounds,
-                false);
-        return rect;
-    }
-
-    /**
-     * Computes the corner of the selection nearest the origin.
-     * @return
-     */
-    private int computeCornerNearestOrigin() {
-        int cornerValue = 0;
-
-        if (mRelativeOrigin.yLocation ==
-                min(mRelativeOrigin.yLocation, mRelativePointer.yLocation)) {
-            cornerValue |= UPPER;
-        } else {
-            cornerValue |= LOWER;
-        }
-
-        if (mRelativeOrigin.xLocation ==
-                min(mRelativeOrigin.xLocation, mRelativePointer.xLocation)) {
-            cornerValue |= LEFT;
-        } else {
-            cornerValue |= RIGHT;
-        }
-
-        return cornerValue;
-    }
-
-    private RelativeCoordinate min(RelativeCoordinate first, RelativeCoordinate second) {
-        return first.compareTo(second) < 0 ? first : second;
-    }
-
-    private RelativeCoordinate max(RelativeCoordinate first, RelativeCoordinate second) {
-        return first.compareTo(second) > 0 ? first : second;
-    }
-
-    /**
-     * @return The absolute coordinate (i.e., the x- or y-value) of the given relative
-     *     coordinate.
-     */
-    private int getCoordinateValue(
-            RelativeCoordinate coordinate, List<Limits> limitsList, boolean isStartOfRange) {
-
-        switch (coordinate.type) {
-            case RelativeCoordinate.BEFORE_FIRST_ITEM:
-                return limitsList.get(0).lowerLimit;
-            case RelativeCoordinate.AFTER_LAST_ITEM:
-                return limitsList.get(limitsList.size() - 1).upperLimit;
-            case RelativeCoordinate.BETWEEN_TWO_ITEMS:
-                if (isStartOfRange) {
-                    return coordinate.limitsAfterCoordinate.lowerLimit;
-                } else {
-                    return coordinate.limitsBeforeCoordinate.upperLimit;
-                }
-            case RelativeCoordinate.WITHIN_LIMITS:
-                return coordinate.limitsBeforeCoordinate.lowerLimit;
-        }
-
-        throw new RuntimeException("Invalid coordinate value.");
-    }
-
-    private boolean areItemsCoveredByBand(
-            RelativePoint first, RelativePoint second) {
-
-        return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
-                doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
-    }
-
-    private boolean doesCoordinateLocationCoverItems(
-            RelativeCoordinate pointerCoordinate, RelativeCoordinate originCoordinate) {
-
-        if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
-                originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
-            return false;
-        }
-
-        if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
-                originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
-            return false;
-        }
-
-        if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
-                originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
-                pointerCoordinate.limitsBeforeCoordinate.equals(
-                        originCoordinate.limitsBeforeCoordinate) &&
-                pointerCoordinate.limitsAfterCoordinate.equals(
-                        originCoordinate.limitsAfterCoordinate)) {
-            return false;
-        }
-
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/ItemDetailsLookup.java b/src/com/android/documentsui/selection/ItemDetailsLookup.java
deleted file mode 100644
index b56a2bc..0000000
--- a/src/com/android/documentsui/selection/ItemDetailsLookup.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import javax.annotation.Nullable;
-
-/**
- * Provides event handlers w/ access to details about documents details
- * view items Documents in the UI (RecyclerView).
- */
-public abstract class ItemDetailsLookup {
-
-    /** @return true if there is an item under the finger/cursor. */
-    public abstract boolean overItem(MotionEvent e);
-
-    /** @return true if there is an item w/ a stable ID under the finger/cursor. */
-    public abstract boolean overStableItem(MotionEvent e);
-
-    /**
-     * @return true if the event is over an area that can be dragged via touch
-     * or via mouse. List items have a white area that is not draggable.
-     */
-    public abstract boolean inItemDragRegion(MotionEvent e);
-
-    /**
-     * @return true if the event is in the "selection hot spot" region.
-     * The hot spot region instantly selects in touch mode, vs launches.
-     */
-    public abstract boolean inItemSelectRegion(MotionEvent e);
-
-    /**
-     * @return the adapter position of the item under the finger/cursor.
-     */
-    public abstract int getItemPosition(MotionEvent e);
-
-    /**
-     * @return the DocumentDetails for the item under the event, or null.
-     */
-    public abstract @Nullable ItemDetails getItemDetails(MotionEvent e);
-
-    /**
-     * Abstract class providing helper classes with access to information about
-     * RecyclerView item associated with a MotionEvent.
-     */
-    public static abstract class ItemDetails {
-
-        public boolean hasPosition() {
-            return getPosition() > RecyclerView.NO_POSITION;
-        }
-
-        public abstract int getPosition();
-
-        public boolean hasStableId() {
-            return getStableId() != null;
-        }
-
-        public abstract @Nullable String getStableId();
-
-        /**
-         * @return The view type of this ViewHolder.
-         */
-        public abstract int getItemViewType();
-
-        /**
-         * @return true if the event is in an area of the item that should be
-         * directly interpreted as a user wishing to select the item. This
-         * is useful for checkboxes and other UI affordances focused on enabling
-         * selection.
-         */
-        public boolean inSelectionHotspot(MotionEvent e) {
-            return false;
-        }
-
-        /**
-         * Events in the drag region will not be processed as selection events. This
-         * allows the client to implement custom handling for events related to drag
-         * and drop.
-         */
-        public boolean inDragRegion(MotionEvent e) {
-            return false;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ItemDetails) {
-                return equals((ItemDetails) obj);
-            }
-            return false;
-        }
-
-        private boolean equals(ItemDetails other) {
-            return this.getPosition() == other.getPosition()
-                    && this.getStableId() == other.getStableId();
-        }
-
-        @Override
-        public int hashCode() {
-            return getPosition() >>> 8;
-        }
-    }
-}
diff --git a/src/com/android/documentsui/selection/MotionEvents.java b/src/com/android/documentsui/selection/MotionEvents.java
deleted file mode 100644
index 1915c5a..0000000
--- a/src/com/android/documentsui/selection/MotionEvents.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import android.graphics.Point;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-/**
- * Utility methods for working with {@link MotionEvent} instances.
- */
-final class MotionEvents {
-
-    private MotionEvents() {}
-
-    static boolean isMouseEvent(MotionEvent e) {
-        return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
-    }
-
-    static boolean isTouchEvent(MotionEvent e) {
-        return e.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER;
-    }
-
-    static boolean isActionMove(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_MOVE;
-    }
-
-    static boolean isActionDown(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_DOWN;
-    }
-
-    static boolean isActionUp(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_UP;
-    }
-
-    static boolean isActionPointerUp(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_POINTER_UP;
-    }
-
-    static boolean isActionPointerDown(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN;
-    }
-
-    static boolean isActionCancel(MotionEvent e) {
-        return e.getActionMasked() == MotionEvent.ACTION_CANCEL;
-    }
-
-    static Point getOrigin(MotionEvent e) {
-        return new Point((int) e.getX(), (int) e.getY());
-    }
-
-    static boolean isPrimaryButtonPressed(MotionEvent e) {
-        return e.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
-    }
-
-    public static boolean isSecondaryButtonPressed(MotionEvent e) {
-        return e.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
-    }
-
-    public static boolean isTertiaryButtonPressed(MotionEvent e) {
-        return e.isButtonPressed(MotionEvent.BUTTON_TERTIARY);
-    }
-
-    static boolean isShiftKeyPressed(MotionEvent e) {
-        return hasBit(e.getMetaState(), KeyEvent.META_SHIFT_ON);
-    }
-
-    static boolean isCtrlKeyPressed(MotionEvent e) {
-        return hasBit(e.getMetaState(), KeyEvent.META_CTRL_ON);
-    }
-
-    static boolean isAltKeyPressed(MotionEvent e) {
-        return hasBit(e.getMetaState(), KeyEvent.META_ALT_ON);
-    }
-
-    public static boolean isTouchpadScroll(MotionEvent e) {
-        // Touchpad inputs are treated as mouse inputs, and when scrolling, there are no buttons
-        // returned.
-        return isMouseEvent(e) && isActionMove(e) && e.getButtonState() == 0;
-    }
-
-    private static boolean hasBit(int metaState, int bit) {
-        return (metaState & bit) != 0;
-    }
-}
diff --git a/src/com/android/documentsui/selection/MotionInputHandler.java b/src/com/android/documentsui/selection/MotionInputHandler.java
deleted file mode 100644
index 474e17d..0000000
--- a/src/com/android/documentsui/selection/MotionInputHandler.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-
-/**
- * Base class for handlers that can be registered w/ {@link GestureRouter}.
- */
-public abstract class MotionInputHandler extends SimpleOnGestureListener {
-
-    protected final SelectionHelper mSelectionHelper;
-    protected final ItemDetailsLookup mDetailsLookup;
-
-    private final Callbacks mCallbacks;
-
-    public MotionInputHandler(
-            SelectionHelper selectionHelper,
-            ItemDetailsLookup detailsLookup,
-            Callbacks callbacks) {
-
-        checkArgument(selectionHelper != null);
-        checkArgument(detailsLookup != null);
-        checkArgument(callbacks != null);
-
-        mSelectionHelper = selectionHelper;
-        mDetailsLookup = detailsLookup;
-        mCallbacks = callbacks;
-    }
-
-    protected final boolean selectItem(ItemDetails details) {
-        checkArgument(details != null);
-        checkArgument(details.hasPosition());
-        checkArgument(details.hasStableId());
-
-        if (mSelectionHelper.select(details.getStableId())) {
-            mSelectionHelper.anchorRange(details.getPosition());
-        }
-
-        // we set the focus on this doc so it will be the origin for keyboard events or shift+clicks
-        // if there is only a single item selected, otherwise clear focus
-        if (mSelectionHelper.getSelection().size() == 1) {
-            mCallbacks.focusItem(details);
-        } else {
-            mCallbacks.clearFocus();
-        }
-        return true;
-    }
-
-    protected final boolean focusItem(ItemDetails details) {
-        checkArgument(details != null);
-        checkArgument(details.hasStableId());
-
-        mSelectionHelper.clearSelection();
-        mCallbacks.focusItem(details);
-        return true;
-    }
-
-    protected final void extendSelectionRange(ItemDetails details) {
-        checkArgument(details.hasPosition());
-        checkArgument(details.hasStableId());
-
-        mSelectionHelper.extendRange(details.getPosition());
-        mCallbacks.focusItem(details);
-    }
-
-    protected final boolean isRangeExtension(MotionEvent e) {
-        return MotionEvents.isShiftKeyPressed(e) && mSelectionHelper.isRangeActive();
-    }
-
-    protected boolean shouldClearSelection(MotionEvent e, ItemDetails item) {
-        return !MotionEvents.isCtrlKeyPressed(e)
-                && !item.inSelectionHotspot(e)
-                && !mSelectionHelper.isSelected(item.getStableId());
-    }
-
-    public static abstract class Callbacks {
-        public abstract void onPerformHapticFeedback();
-        public void focusItem(ItemDetails item) {}
-        public void clearFocus() {}
-    }
-}
diff --git a/src/com/android/documentsui/selection/MouseInputHandler.java b/src/com/android/documentsui/selection/MouseInputHandler.java
deleted file mode 100644
index 7ceb0f5..0000000
--- a/src/com/android/documentsui/selection/MouseInputHandler.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static com.android.documentsui.selection.Shared.DEBUG;
-import static com.android.documentsui.selection.Shared.VERBOSE;
-
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.internal.widget.RecyclerView;
-
-import javax.annotation.Nullable;
-
-/**
- * A MotionInputHandler that provides the high-level glue for mouse/stylus driven selection. This
- * class works with {@link RecyclerView}, {@link GestureRouter}, and {@link GestureSelectionHelper}
- * to provide robust user drive selection support.
- */
-public final class MouseInputHandler extends MotionInputHandler {
-
-        private static final String TAG = "MouseInputDelegate";
-
-        private final Callbacks mCallbacks;
-
-        // The event has been handled in onSingleTapUp
-        private boolean mHandledTapUp;
-        // true when the previous event has consumed a right click motion event
-        private boolean mHandledOnDown;
-
-        public MouseInputHandler(
-                SelectionHelper selectionHelper,
-                ItemDetailsLookup detailsLookup,
-                Callbacks callbacks) {
-
-            super(selectionHelper, detailsLookup, callbacks);
-
-            mCallbacks = callbacks;
-        }
-
-        @Override
-        public boolean onDown(MotionEvent e) {
-            if (VERBOSE) Log.v(TAG, "Delegated onDown event.");
-            if ((MotionEvents.isAltKeyPressed(e) && MotionEvents.isPrimaryButtonPressed(e))
-                    || MotionEvents.isSecondaryButtonPressed(e)) {
-                mHandledOnDown = true;
-                return onRightClick(e);
-            }
-
-            return false;
-        }
-
-        @Override
-        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-            // Don't scroll content window in response to mouse drag
-            // If it's two-finger trackpad scrolling, we want to scroll
-            return !MotionEvents.isTouchpadScroll(e2);
-        }
-
-        @Override
-        public boolean onSingleTapUp(MotionEvent e) {
-            // See b/27377794. Since we don't get a button state back from UP events, we have to
-            // explicitly save this state to know whether something was previously handled by
-            // DOWN events or not.
-            if (mHandledOnDown) {
-                if (VERBOSE) Log.v(TAG, "Ignoring onSingleTapUp, previously handled in onDown.");
-                mHandledOnDown = false;
-                return false;
-            }
-
-            if (!mDetailsLookup.overStableItem(e)) {
-                if (DEBUG) Log.d(TAG, "Tap not associated w/ model item. Clearing selection.");
-                mSelectionHelper.clearSelection();
-                mCallbacks.clearFocus();
-                return false;
-            }
-
-            if (MotionEvents.isTertiaryButtonPressed(e)) {
-                if (DEBUG) Log.d(TAG, "Ignoring middle click");
-                return false;
-            }
-
-            ItemDetails item = mDetailsLookup.getItemDetails(e);
-            if (mSelectionHelper.hasSelection()) {
-                if (isRangeExtension(e)) {
-                    extendSelectionRange(item);
-                } else {
-                    if (shouldClearSelection(e, item)) {
-                        mSelectionHelper.clearSelection();
-                    }
-                    if (mSelectionHelper.isSelected(item.getStableId())) {
-                        if (mSelectionHelper.deselect(item.getStableId())) {
-                            mCallbacks.clearFocus();
-                        }
-                    } else {
-                        selectOrFocusItem(item, e);
-                    }
-                }
-                mHandledTapUp = true;
-                return true;
-            }
-
-            return false;
-        }
-
-        @Override
-        public boolean onSingleTapConfirmed(MotionEvent e) {
-            if (mHandledTapUp) {
-                if (VERBOSE) Log.v(TAG,
-                        "Ignoring onSingleTapConfirmed, previously handled in onSingleTapUp.");
-                mHandledTapUp = false;
-                return false;
-            }
-
-            if (mSelectionHelper.hasSelection()) {
-                return false;  // should have been handled by onSingleTapUp.
-            }
-
-            if (!mDetailsLookup.overItem(e)) {
-                if (DEBUG) Log.d(TAG, "Ignoring Confirmed Tap on non-item.");
-                return false;
-            }
-
-            if (MotionEvents.isTertiaryButtonPressed(e)) {
-                if (DEBUG) Log.d(TAG, "Ignoring middle click");
-                return false;
-            }
-
-            @Nullable ItemDetails item = mDetailsLookup.getItemDetails(e);
-            if (item == null || !item.hasStableId()) {
-                Log.w(TAG, "Ignoring Confirmed Tap. No document details associated w/ event.");
-                return false;
-            }
-
-            if (mCallbacks.hasFocusedItem() && MotionEvents.isShiftKeyPressed(e)) {
-                mSelectionHelper.startRange(mCallbacks.getFocusedPosition());
-                mSelectionHelper.extendRange(item.getPosition());
-            } else {
-                selectOrFocusItem(item, e);
-            }
-            return true;
-        }
-
-        @Override
-        public boolean onDoubleTap(MotionEvent e) {
-            mHandledTapUp = false;
-
-            if (!mDetailsLookup.overStableItem(e)) {
-                if (DEBUG) Log.d(TAG, "Ignoring DoubleTap on non-model-backed item.");
-                return false;
-            }
-
-            if (MotionEvents.isTertiaryButtonPressed(e)) {
-                if (DEBUG) Log.d(TAG, "Ignoring middle click");
-                return false;
-            }
-
-            @Nullable ItemDetails item = mDetailsLookup.getItemDetails(e);
-            if (item != null) {
-                return mCallbacks.onItemActivated(item, e);
-            }
-
-            return false;
-        }
-
-        private boolean onRightClick(MotionEvent e) {
-            if (mDetailsLookup.overStableItem(e)) {
-                @Nullable ItemDetails item = mDetailsLookup.getItemDetails(e);
-                if (item != null && !mSelectionHelper.isSelected(item.getStableId())) {
-                    mSelectionHelper.clearSelection();
-                    selectItem(item);
-                }
-            }
-
-            // We always delegate final handling of the event,
-            // since the handler might want to show a context menu
-            // in an empty area or some other weirdo view.
-            return mCallbacks.onContextClick(e);
-        }
-
-        private void selectOrFocusItem(ItemDetails item, MotionEvent e) {
-            if (item.inSelectionHotspot(e) || MotionEvents.isCtrlKeyPressed(e)) {
-                selectItem(item);
-            } else {
-                focusItem(item);
-            }
-        }
-
-        public static abstract class Callbacks extends MotionInputHandler.Callbacks {
-            public abstract boolean onItemActivated(ItemDetails item, MotionEvent e);
-            public boolean onContextClick(MotionEvent e) {
-                return false;
-            }
-            public boolean hasFocusedItem() {
-                return false;
-            }
-            public int getFocusedPosition() {
-                return RecyclerView.NO_POSITION;
-            }
-        }
-    }
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/MutableSelection.java b/src/com/android/documentsui/selection/MutableSelection.java
deleted file mode 100644
index 7939e14..0000000
--- a/src/com/android/documentsui/selection/MutableSelection.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-/**
- * Subclass of Selection exposing public support for mutating the underlying selection data.
- * This is useful for clients of {@link SelectionHelper} that wish to manipulate
- * a copy of selection data obtained via {@link SelectionHelper#copySelection(Selection)}.
- */
-public final class MutableSelection extends Selection {
-
-    @Override
-    public boolean add(String id) {
-        return super.add(id);
-    }
-
-    @Override
-    public boolean remove(String id) {
-        return super.remove(id);
-    }
-
-    @Override
-    public void clear() {
-        super.clear();
-    }
-}
diff --git a/src/com/android/documentsui/selection/Range.java b/src/com/android/documentsui/selection/Range.java
deleted file mode 100644
index efe49e9..0000000
--- a/src/com/android/documentsui/selection/Range.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-import static android.support.v7.widget.RecyclerView.NO_POSITION;
-import static com.android.documentsui.selection.Shared.DEBUG;
-import static com.android.documentsui.selection.Shared.TAG;
-
-import android.util.Log;
-
-import com.android.documentsui.selection.DefaultSelectionHelper.RangeType;
-
-/**
- * Class providing support for managing range selections.
- */
-final class Range {
-
-    private final Callbacks mCallbacks;
-    private final int mBegin;
-    private int mEnd = NO_POSITION;
-
-    public Range(Callbacks callbacks, int begin) {
-        if (DEBUG) Log.d(TAG, "New Ranger created beginning @ " + begin);
-        mCallbacks = callbacks;
-        mBegin = begin;
-    }
-
-    void extendSelection(int position, @RangeType int type) {
-        checkArgument(position != NO_POSITION, "Position cannot be NO_POSITION.");
-
-        if (mEnd == NO_POSITION || mEnd == mBegin) {
-            // Reset mEnd so it can be established in establishRange.
-            mEnd = NO_POSITION;
-            establishRange(position, type);
-        } else {
-            reviseRange(position, type);
-        }
-    }
-
-    private void establishRange(int position, @RangeType int type) {
-        checkArgument(mEnd == NO_POSITION, "End has already been set.");
-
-        if (position == mBegin) {
-            mEnd = position;
-        }
-
-        if (position > mBegin) {
-            updateRange(mBegin + 1, position, true, type);
-        } else if (position < mBegin) {
-            updateRange(position, mBegin - 1, true, type);
-        }
-
-        mEnd = position;
-    }
-
-    private void reviseRange(int position, @RangeType int type) {
-        checkArgument(mEnd != NO_POSITION, "End must already be set.");
-        checkArgument(mBegin != mEnd, "Beging and end point to same position.");
-
-        if (position == mEnd) {
-            if (DEBUG) Log.v(TAG, "Ignoring no-op revision for range: " + this);
-        }
-
-        if (mEnd > mBegin) {
-            reviseAscendingRange(position, type);
-        } else if (mEnd < mBegin) {
-            reviseDescendingRange(position, type);
-        }
-        // the "else" case is covered by checkState at beginning of method.
-
-        mEnd = position;
-    }
-
-    /**
-     * Updates an existing ascending selection.
-     * @param position
-     */
-    private void reviseAscendingRange(int position, @RangeType int type) {
-        // Reducing or reversing the range....
-        if (position < mEnd) {
-            if (position < mBegin) {
-                updateRange(mBegin + 1, mEnd, false, type);
-                updateRange(position, mBegin -1, true, type);
-            } else {
-                updateRange(position + 1, mEnd, false, type);
-            }
-        }
-
-        // Extending the range...
-        else if (position > mEnd) {
-            updateRange(mEnd + 1, position, true, type);
-        }
-    }
-
-    private void reviseDescendingRange(int position, @RangeType int type) {
-        // Reducing or reversing the range....
-        if (position > mEnd) {
-            if (position > mBegin) {
-                updateRange(mEnd, mBegin - 1, false, type);
-                updateRange(mBegin + 1, position, true, type);
-            } else {
-                updateRange(mEnd, position - 1, false, type);
-            }
-        }
-
-        // Extending the range...
-        else if (position < mEnd) {
-            updateRange(position, mEnd - 1, true, type);
-        }
-    }
-
-    /**
-     * Try to set selection state for all elements in range. Not that callbacks can cancel
-     * selection of specific items, so some or even all items may not reflect the desired state
-     * after the update is complete.
-     *
-     * @param begin Adapter position for range start (inclusive).
-     * @param end Adapter position for range end (inclusive).
-     * @param selected New selection state.
-     */
-    private void updateRange(int begin, int end, boolean selected, @RangeType int type) {
-        mCallbacks.updateForRange(begin, end, selected, type);
-    }
-
-    @Override
-    public String toString() {
-        return "Range{begin=" + mBegin + ", end=" + mEnd + "}";
-    }
-
-    /*
-     * @see {@link DefaultSelectionHelper#updateForRange(int, int , boolean, int)}.
-     */
-    static abstract class Callbacks {
-        abstract void updateForRange(
-                int begin, int end, boolean selected, @RangeType int type);
-    }
-}
diff --git a/src/com/android/documentsui/selection/Selection.java b/src/com/android/documentsui/selection/Selection.java
deleted file mode 100644
index 88b4cbb..0000000
--- a/src/com/android/documentsui/selection/Selection.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Object representing the current selection and provisional selection. Provides read only public
- * access, and private write access.
- * <p>
- * This class tracks selected items by managing two sets:
- *
- * <li>primary selection
- *
- * Primary selection consists of items tapped by a user or by lassoed by band select operation.
- *
- * <li>provisional selection
- *
- * Provisional selections are selections which have been temporarily created
- * by an in-progress band select or gesture selection. Once the user releases the mouse button
- * or lifts their finger the corresponding provisional selection should be converted into
- * primary selection.
- *
- * <p>The total selection is the combination of
- * both the core selection and the provisional selection. Tracking both separately is necessary to
- * ensure that items in the core selection are not "erased" from the core selection when they
- * are temporarily included in a secondary selection (like band selection).
- */
-public class Selection implements Iterable<String>, Parcelable {
-
-    final Set<String> mSelection;
-    final Set<String> mProvisionalSelection;
-
-    public Selection() {
-        mSelection = new HashSet<>();
-        mProvisionalSelection = new HashSet<>();
-    }
-
-    /**
-     * Used by CREATOR.
-     */
-    private Selection(Set<String> selection) {
-        mSelection = selection;
-        mProvisionalSelection = new HashSet<>();
-    }
-
-    /**
-     * @param id
-     * @return true if the position is currently selected.
-     */
-    public boolean contains(@Nullable String id) {
-        return mSelection.contains(id) || mProvisionalSelection.contains(id);
-    }
-
-    /**
-     * Returns an {@link Iterator} that iterators over the selection, *excluding*
-     * any provisional selection.
-     *
-     * {@inheritDoc}
-     */
-    @Override
-    public Iterator<String> iterator() {
-        return mSelection.iterator();
-    }
-
-    /**
-     * @return size of the selection including both final and provisional selected items.
-     */
-    public int size() {
-        return mSelection.size() + mProvisionalSelection.size();
-    }
-
-    /**
-     * @return true if the selection is empty.
-     */
-    public boolean isEmpty() {
-        return mSelection.isEmpty() && mProvisionalSelection.isEmpty();
-    }
-
-    /**
-     * Sets the provisional selection, which is a temporary selection that can be saved,
-     * canceled, or adjusted at a later time. When a new provision selection is applied, the old
-     * one (if it exists) is abandoned.
-     * @return Map of ids added or removed. Added ids have a value of true, removed are false.
-     */
-    Map<String, Boolean> setProvisionalSelection(Set<String> newSelection) {
-        Map<String, Boolean> delta = new HashMap<>();
-
-        for (String id: mProvisionalSelection) {
-            // Mark each item that used to be in the provisional selection
-            // but is not in the new provisional selection.
-            if (!newSelection.contains(id) && !mSelection.contains(id)) {
-                delta.put(id, false);
-            }
-        }
-
-        for (String id: mSelection) {
-            // Mark each item that used to be in the selection but is unsaved and not in the new
-            // provisional selection.
-            if (!newSelection.contains(id)) {
-                delta.put(id, false);
-            }
-        }
-
-        for (String id: newSelection) {
-            // Mark each item that was not previously in the selection but is in the new
-            // provisional selection.
-            if (!mSelection.contains(id) && !mProvisionalSelection.contains(id)) {
-                delta.put(id, true);
-            }
-        }
-
-        // Now, iterate through the changes and actually add/remove them to/from the current
-        // selection. This could not be done in the previous loops because changing the size of
-        // the selection mid-iteration changes iteration order erroneously.
-        for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
-            String id = entry.getKey();
-            if (entry.getValue()) {
-                mProvisionalSelection.add(id);
-            } else {
-                mProvisionalSelection.remove(id);
-            }
-        }
-
-        return delta;
-    }
-
-    /**
-     * Saves the existing provisional selection. Once the provisional selection is saved,
-     * subsequent provisional selections which are different from this existing one cannot
-     * cause items in this existing provisional selection to become deselected.
-     */
-    @VisibleForTesting
-    protected void mergeProvisionalSelection() {
-        mSelection.addAll(mProvisionalSelection);
-        mProvisionalSelection.clear();
-    }
-
-    /**
-     * Abandons the existing provisional selection so that all items provisionally selected are
-     * now deselected.
-     */
-    @VisibleForTesting
-    void clearProvisionalSelection() {
-        mProvisionalSelection.clear();
-    }
-
-    /**
-     * Adds a new item to the primary selection.
-     *
-     * @return true if the operation resulted in a modification to the selection.
-     */
-    boolean add(String id) {
-        if (mSelection.contains(id)) {
-            return false;
-        }
-
-        mSelection.add(id);
-        return true;
-    }
-
-    /**
-     * Removes an item from the primary selection.
-     *
-     * @return true if the operation resulted in a modification to the selection.
-     */
-    boolean remove(String id) {
-        if (!mSelection.contains(id)) {
-            return false;
-        }
-
-        mSelection.remove(id);
-        return true;
-    }
-
-    /**
-     * Clears the primary selection. The provisional selection, if any, is unaffected.
-     */
-    void clear() {
-        mSelection.clear();
-    }
-
-    /**
-     * Trims this selection to be the intersection of itself and {@code ids}.
-     */
-    void intersect(Collection<String> ids) {
-        checkArgument(ids != null);
-
-        mSelection.retainAll(ids);
-        mProvisionalSelection.retainAll(ids);
-    }
-
-    /**
-     * Clones primary and provisional selection from supplied {@link Selection}.
-     * Does not copy active range data.
-     */
-    @VisibleForTesting
-    void copyFrom(Selection source) {
-        mSelection.clear();
-        mSelection.addAll(source.mSelection);
-
-        mProvisionalSelection.clear();
-        mProvisionalSelection.addAll(source.mProvisionalSelection);
-    }
-
-    @Override
-    public String toString() {
-        if (size() <= 0) {
-            return "size=0, items=[]";
-        }
-
-        StringBuilder buffer = new StringBuilder(size() * 28);
-        buffer.append("Selection{")
-            .append("primary{size=" + mSelection.size())
-            .append(", entries=" + mSelection)
-            .append("}, provisional{size=" + mProvisionalSelection.size())
-            .append(", entries=" + mProvisionalSelection)
-            .append("}}");
-        return buffer.toString();
-    }
-
-    @Override
-    public int hashCode() {
-        return mSelection.hashCode() ^ mProvisionalSelection.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        return other instanceof Selection
-            ? equals((Selection) other)
-            : false;
-    }
-
-    private boolean equals(Selection other) {
-        return mSelection.equals(((Selection) other).mSelection) &&
-                mProvisionalSelection.equals(((Selection) other).mProvisionalSelection);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStringList(new ArrayList<>(mSelection));
-        // We don't include provisional selection since it is
-        // typically coupled to some other runtime state (like a band).
-    }
-
-    public static final ClassLoaderCreator<Selection> CREATOR =
-            new ClassLoaderCreator<Selection>() {
-        @Override
-        public Selection createFromParcel(Parcel in) {
-            return createFromParcel(in, null);
-        }
-
-        @Override
-        public Selection createFromParcel(Parcel in, ClassLoader loader) {
-            ArrayList<String> selected = new ArrayList<>();
-            in.readStringList(selected);
-
-            return new Selection(new HashSet<>(selected));
-        }
-
-        @Override
-        public Selection[] newArray(int size) {
-            return new Selection[size];
-        }
-    };
-}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/SelectionHelper.java b/src/com/android/documentsui/selection/SelectionHelper.java
deleted file mode 100644
index bd8b34e..0000000
--- a/src/com/android/documentsui/selection/SelectionHelper.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * SelectionManager provides support for managing selection within a RecyclerView instance.
- *
- * @see DefaultSelectionHelper for details on instantiation.
- */
-public abstract class SelectionHelper {
-
-    /**
-     * This value is included in the payload when SelectionHelper implementations
-     * notify RecyclerView of changes. Clients can look for this in
-     * {@code onBindViewHolder} to know if the bind event is occurring in response
-     * to a selection state change.
-     */
-    public static final String SELECTION_CHANGED_MARKER = "Selection-Changed";
-
-    /**
-     * Adds {@code observe} to be notified when changes to selection occur.
-     *
-     * @param observer
-     */
-    public abstract void addObserver(SelectionObserver observer);
-
-    public abstract boolean hasSelection();
-
-    /**
-     * Returns a Selection object that provides a live view on the current selection.
-     *
-     * @see #copySelection(Selection) on how to get a snapshot
-     *     of the selection that will not reflect future changes
-     *     to selection.
-     *
-     * @return The current selection.
-     */
-    public abstract Selection getSelection();
-
-    /**
-     * Updates {@code dest} to reflect the current selection.
-     * @param dest
-     */
-    public abstract void copySelection(Selection dest);
-
-    /**
-     * @return true if the item specified by its id is selected. Shorthand for
-     * {@code getSelection().contains(String)}.
-     */
-    public abstract boolean isSelected(String id);
-
-    /**
-     * Restores the selected state of specified items. Used in cases such as restore the selection
-     * after rotation etc. Provisional selection, being provisional 'n all, isn't restored.
-     */
-    public abstract void restoreSelection(Selection other);
-
-    /**
-     * Sets the selected state of the specified items. Note that the callback will NOT
-     * be consulted to see if an item can be selected.
-     *
-     * @param ids
-     * @param selected
-     * @return
-     */
-    public abstract boolean setItemsSelected(Iterable<String> ids, boolean selected);
-
-    /**
-     * Clears the selection and notifies (if something changes).
-     */
-    public abstract void clearSelection();
-
-    /**
-     * Attempts to select an item.
-     *
-     * @return true if the item was selected. False if the item was not selected, or was
-     *         was already selected prior to the method being called.
-     */
-    public abstract boolean select(String itemId);
-
-    /**
-     * Attempts to deselect an item.
-     *
-     * @return true if the item was deselected. False if the item was not deselected, or was
-     *         was already deselected prior to the method being called.
-     */
-    public abstract boolean deselect(String itemId);
-
-    /**
-     * Starts a range selection. If a range selection is already active, this will start a new range
-     * selection (which will reset the range anchor).
-     *
-     * @param pos The anchor position for the selection range.
-     */
-    public abstract void startRange(int pos);
-
-    /**
-     * Sets the end point for the active range selection.
-     *
-     * <p>This function should only be called when a range selection is active
-     * (see {@link #isRangeActive()}. Items in the range [anchor, end] will be
-     * selected.
-     *
-     * @param pos The new end position for the selection range.
-     * @param type The type of selection the range should utilize.
-     *
-     * @throws IllegalStateException if a range selection is not active. Range selection
-     *         must have been started by a call to {@link #startRange(int)}.
-     */
-    public abstract void extendRange(int pos);
-
-    /**
-     * Stops an in-progress range selection. All selection done with
-     * {@link #extendProvisionalRange(int)} will be lost if
-     * {@link Selection#mergeProvisionalSelection()} is not called beforehand.
-     */
-    public abstract void endRange();
-
-    /**
-     * @return Whether or not there is a current range selection active.
-     */
-    public abstract boolean isRangeActive();
-
-    /**
-     * Sets the magic location at which a selection range begins (the selection anchor). This value
-     * is consulted when determining how to extend, and modify selection ranges. Calling this when a
-     * range selection is active will reset the range selection.
-     */
-    public abstract void anchorRange(int position);
-
-    /**
-     * @param pos
-     */
-    // TODO: This is smelly. Maybe this type of logic needs to move into range selection,
-    // then selection manager can have a startProvisionalRange and startRange. Or
-    // maybe ranges always start life as provisional.
-    public abstract void extendProvisionalRange(int pos);
-
-    /**
-     * @param newSelection
-     */
-    public abstract void setProvisionalSelection(Set<String> newSelection);
-
-    /**
-     *
-     */
-    public abstract void clearProvisionalSelection();
-
-    public abstract void mergeProvisionalSelection();
-
-    /**
-     * Observer interface providing access to information about Selection state changes.
-     */
-    public static abstract class SelectionObserver {
-
-        /**
-         * Called when state of an item has been changed.
-         */
-        public void onItemStateChanged(String id, boolean selected) {}
-
-        /**
-         * Called when the underlying data set has change. After this method is called
-         * the selection manager will attempt traverse the existing selection,
-         * calling {@link #onItemStateChanged(String, boolean)} for each selected item,
-         * and deselecting any items that cannot be selected given the updated dataset.
-         */
-        public void onSelectionReset() {}
-
-        /**
-         * Called immediately after completion of any set of changes, excluding
-         * those resulting in calls to {@link #onSelectionReset()} and
-         * {@link #onSelectionRestored()}.
-         */
-        public void onSelectionChanged() {}
-
-        /**
-         * Called immediately after selection is restored.
-         * {@link #onItemStateChanged(String, boolean)} will not be called
-         * for individual items in the selection.
-         */
-        public void onSelectionRestored() {}
-    }
-
-    /**
-     * Facilitates the use of stable ids.
-     */
-    public static abstract class StableIdProvider {
-        /**
-         * @return The model ID of the item at the given adapter position.
-         */
-        public abstract String getStableId(int position);
-
-        /**
-         * @return the position of a stable ID, or RecyclerView.NO_POSITION.
-         */
-        public abstract int getPosition(String id);
-
-        /**
-         * @return A list of all known stable IDs.
-         */
-        public abstract List<String> getStableIds();
-    }
-
-    /**
-     * Implement SelectionPredicate to control when items can be selected or unselected.
-     */
-    public static abstract class SelectionPredicate {
-
-        /** @return true if the item at {@code id} can be set to {@code nextState}. */
-        public abstract boolean canSetStateForId(String id, boolean nextState);
-
-        /** @return true if the item at {@code id} can be set to {@code nextState}. */
-        public abstract boolean canSetStateAtPosition(int position, boolean nextState);
-
-        /** @return true if more than a single item can be selected. */
-        public boolean canSelectMultiple() {
-            return true;
-        }
-    }
-}
diff --git a/src/com/android/documentsui/selection/Shared.java b/src/com/android/documentsui/selection/Shared.java
deleted file mode 100644
index bf30919..0000000
--- a/src/com/android/documentsui/selection/Shared.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-/**
- * Shared constants used in this and descendant packages.
- */
-public final class Shared {
-
-    public static final String TAG = "SelectionHelper";
-    public static final boolean DEBUG = false;
-    public static final boolean VERBOSE = false;
-
-    private Shared() {}
-}
diff --git a/src/com/android/documentsui/selection/ToolHandlerRegistry.java b/src/com/android/documentsui/selection/ToolHandlerRegistry.java
deleted file mode 100644
index 65f9f2e..0000000
--- a/src/com/android/documentsui/selection/ToolHandlerRegistry.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-import static android.support.v4.util.Preconditions.checkState;
-
-import android.support.annotation.Nullable;
-import android.view.MotionEvent;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Registry for tool specific event handler.
- */
-final class ToolHandlerRegistry<T> {
-
-    // Currently there are four known input types. ERASER is the last one, so has the
-    // highest value. UNKNOWN is zero, so we add one. This allows delegates to be
-    // registered by type, and avoid the auto-boxing that would be necessary were we
-    // to store delegates in a Map<Integer, Delegate>.
-    private static final int sNumInputTypes = MotionEvent.TOOL_TYPE_ERASER + 1;
-
-    private final List<T> mHandlers = Arrays.asList(null, null, null, null, null);
-    private final T mDefault;
-
-    ToolHandlerRegistry(T defaultDelegate) {
-        checkArgument(defaultDelegate != null);
-        mDefault = defaultDelegate;
-
-        // Initialize all values to null.
-        for (int i = 0; i < sNumInputTypes; i++) {
-            mHandlers.set(i, null);
-        }
-    }
-
-    /**
-     * @param toolType
-     * @param delegate the delegate, or null to unregister.
-     * @throws IllegalStateException if an tooltype handler is already registered.
-     */
-    void set(int toolType, @Nullable T delegate) {
-        checkArgument(toolType >= 0 && toolType <= MotionEvent.TOOL_TYPE_ERASER);
-        checkState(mHandlers.get(toolType) == null);
-
-        mHandlers.set(toolType, delegate);
-    }
-
-    T get(MotionEvent e) {
-        T d = mHandlers.get(e.getToolType(0));
-        return d != null ? d : mDefault;
-    }
-}
diff --git a/src/com/android/documentsui/selection/TouchEventRouter.java b/src/com/android/documentsui/selection/TouchEventRouter.java
deleted file mode 100644
index 50585fe..0000000
--- a/src/com/android/documentsui/selection/TouchEventRouter.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-
-/**
- * A class responsible for routing MotionEvents to tool-type specific handlers,
- * and if not handled by a handler, on to a {@link GestureDetector} for further
- * processing.
- *
- * <p>TouchEventRouter takes its name from
- * {@link RecyclerView#addOnItemTouchListener(OnItemTouchListener)}. Despite "Touch"
- * being in the name, it receives MotionEvents for all types of tools.
- */
-public final class TouchEventRouter implements OnItemTouchListener {
-
-    private final GestureDetector mDetector;
-    private final ToolHandlerRegistry<OnItemTouchListener> mDelegates;
-
-    public TouchEventRouter(GestureDetector detector, OnItemTouchListener defaultDelegate) {
-        checkArgument(detector != null);
-        checkArgument(defaultDelegate != null);
-
-        mDetector = detector;
-        mDelegates = new ToolHandlerRegistry<>(defaultDelegate);
-    }
-
-    public TouchEventRouter(GestureDetector detector) {
-        this(
-                detector,
-                // Default listener does nothing.
-                new OnItemTouchListener() {
-                    @Override
-                    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
-                        return false;
-                    }
-
-                    @Override
-                    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
-                    }
-
-                    @Override
-                    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-                    }
-                });
-    }
-
-    /**
-     * @param toolType See MotionEvent for details on available types.
-     * @param delegate An {@link OnItemTouchListener} to receive events
-     *     of {@code toolType}.
-     */
-    public void register(int toolType, OnItemTouchListener delegate) {
-        checkArgument(delegate != null);
-        mDelegates.set(toolType, delegate);
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
-        boolean handled = mDelegates.get(e).onInterceptTouchEvent(rv, e);
-
-        // Forward all events to UserInputHandler.
-        // This is necessary since UserInputHandler needs to always see the first DOWN event. Or
-        // else all future UP events will be tossed.
-        handled |= mDetector.onTouchEvent(e);
-
-        return handled;
-    }
-
-    @Override
-    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
-        mDelegates.get(e).onTouchEvent(rv, e);
-
-        // Note: even though this event is being handled as part of gestures such as drag and band,
-        // continue forwarding to the GestureDetector. The detector needs to see the entire cluster
-        // of events in order to properly interpret other gestures, such as long press.
-        mDetector.onTouchEvent(e);
-    }
-
-    @Override
-    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
-}
diff --git a/src/com/android/documentsui/selection/TouchInputHandler.java b/src/com/android/documentsui/selection/TouchInputHandler.java
deleted file mode 100644
index 298d54b..0000000
--- a/src/com/android/documentsui/selection/TouchInputHandler.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static com.android.documentsui.base.SharedMinimal.DEBUG;
-
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-
-/**
- * A MotionInputHandler that provides the high-level glue for touch driven selection. This class
- * works with {@link RecyclerView}, {@link GestureRouter}, and {@link GestureSelectionHelper} to
- * provide robust user drive selection support.
- */
-public final class TouchInputHandler extends MotionInputHandler {
-    private static final String TAG = "TouchInputDelegate";
-
-    private final SelectionPredicate mSelectionPredicate;
-    private final Callbacks mCallbacks;
-    private final Runnable mGestureKicker;
-
-    public TouchInputHandler(
-            SelectionHelper selectionHelper,
-            ItemDetailsLookup detailsLookup,
-            SelectionPredicate selectionPredicate,
-            Runnable gestureKicker,
-            Callbacks callbacks) {
-
-        super(selectionHelper, detailsLookup, callbacks);
-
-        mSelectionPredicate = selectionPredicate;
-        mGestureKicker = gestureKicker;
-        mCallbacks = callbacks;
-    }
-
-    public TouchInputHandler(
-            SelectionHelper selectionHelper,
-            ItemDetailsLookup detailsLookup,
-            SelectionPredicate selectionPredicate,
-            GestureSelectionHelper gestureHelper,
-            Callbacks callbacks) {
-
-        this(
-                selectionHelper,
-                detailsLookup,
-                selectionPredicate,
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        gestureHelper.start();
-                    }
-                },
-                callbacks);
-    }
-
-    @Override
-    public boolean onSingleTapUp(MotionEvent e) {
-        if (!mDetailsLookup.overStableItem(e)) {
-            if (DEBUG) Log.d(TAG, "Tap not associated w/ model item. Clearing selection.");
-            mSelectionHelper.clearSelection();
-            return false;
-        }
-
-        ItemDetails item = mDetailsLookup.getItemDetails(e);
-        if (mSelectionHelper.hasSelection()) {
-            if (isRangeExtension(e)) {
-                extendSelectionRange(item);
-            } else if (mSelectionHelper.isSelected(item.getStableId())) {
-                mSelectionHelper.deselect(item.getStableId());
-            } else {
-                selectItem(item);
-            }
-
-            return true;
-        }
-
-        // Touch events select if they occur in the selection hotspot,
-        // otherwise they activate.
-        return item.inSelectionHotspot(e)
-                ? selectItem(item)
-                : mCallbacks.onItemActivated(item, e);
-    }
-
-    @Override
-    public final void onLongPress(MotionEvent e) {
-        if (!mDetailsLookup.overStableItem(e)) {
-            if (DEBUG) Log.d(TAG, "Ignoring LongPress on non-model-backed item.");
-            return;
-        }
-
-        ItemDetails item = mDetailsLookup.getItemDetails(e);
-        boolean handled = false;
-
-        if (isRangeExtension(e)) {
-            extendSelectionRange(item);
-            handled = true;
-        } else {
-            if (!mSelectionHelper.isSelected(item.getStableId())
-                    && mSelectionPredicate.canSetStateForId(item.getStableId(), true)) {
-                // If we cannot select it, we didn't apply anchoring - therefore should not
-                // start gesture selection
-                if (selectItem(item)) {
-                    // And finally if the item was selected && we can select multiple
-                    // we kick off gesture selection.
-                    if (mSelectionPredicate.canSelectMultiple()) {
-                        mGestureKicker.run();
-                    }
-                    handled = true;
-                }
-            } else {
-                // We only initiate drag and drop on long press for touch to allow regular
-                // touch-based scrolling
-                // mTouchDragListener.accept(e);
-                mCallbacks.onDragInitiated(e);
-                handled = true;
-            }
-        }
-
-        if (handled) {
-            mCallbacks.onPerformHapticFeedback();
-        }
-    }
-
-    public static abstract class Callbacks extends MotionInputHandler.Callbacks {
-        public abstract boolean onItemActivated(ItemDetails item, MotionEvent e);
-        public boolean onDragInitiated(MotionEvent e) {
-            return false;
-        }
-    }
-}
diff --git a/src/com/android/documentsui/selection/demo/DemoDetailsLookup.java b/src/com/android/documentsui/selection/demo/DemoDetailsLookup.java
deleted file mode 100644
index 6811125..0000000
--- a/src/com/android/documentsui/selection/demo/DemoDetailsLookup.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.demo;
-
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.documentsui.selection.ItemDetailsLookup;
-
-/**
- * Access to details of an item associated with a {@link MotionEvent} instance.
- */
-final class DemoDetailsLookup extends ItemDetailsLookup {
-
-    private final RecyclerView mRecView;
-
-    public DemoDetailsLookup(RecyclerView view) {
-        mRecView = view;
-    }
-
-    @Override
-    public boolean overItem(MotionEvent e) {
-        return getItemPosition(e) != RecyclerView.NO_POSITION;
-    }
-
-    @Override
-    public boolean overStableItem(MotionEvent e) {
-        return overItem(e) && getItemDetails(e).hasStableId();
-    }
-
-    @Override
-    public boolean inItemDragRegion(MotionEvent e) {
-        return overItem(e) && getItemDetails(e).inDragRegion(e);
-    }
-
-    @Override
-    public boolean inItemSelectRegion(MotionEvent e) {
-        return overItem(e) && getItemDetails(e).inSelectionHotspot(e);
-    }
-
-    @Override
-    public int getItemPosition(MotionEvent e) {
-        View child = mRecView.findChildViewUnder(e.getX(), e.getY());
-        return (child != null)
-                ? mRecView.getChildAdapterPosition(child)
-                : RecyclerView.NO_POSITION;
-    }
-
-    @Override
-    public ItemDetails getItemDetails(MotionEvent e) {
-        @Nullable DemoHolder holder = getDemoHolder(e);
-        return holder == null ? null : holder.getItemDetails();
-    }
-
-    private @Nullable DemoHolder getDemoHolder(MotionEvent e) {
-        View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
-        if (childView != null) {
-            ViewHolder holder = mRecView.getChildViewHolder(childView);
-            if (holder instanceof DemoHolder) {
-                return (DemoHolder) holder;
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/com/android/documentsui/selection/demo/DemoHolder.java b/src/com/android/documentsui/selection/demo/DemoHolder.java
deleted file mode 100644
index 3a783b5..0000000
--- a/src/com/android/documentsui/selection/demo/DemoHolder.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.demo;
-
-import android.graphics.Rect;
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.documentsui.R;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-
-public final class DemoHolder extends RecyclerView.ViewHolder {
-
-        private final LinearLayout mContainer;
-        public final TextView mSelector;
-        public final TextView mLabel;
-        private final Details mDetails;
-        private DemoItem mItem;
-
-        DemoHolder(LinearLayout layout) {
-            super(layout);
-            mContainer = layout.findViewById(R.id.container);
-            mSelector = layout.findViewById(R.id.selector);
-            mLabel = layout.findViewById(R.id.label);
-            mDetails = new Details(this);
-        }
-
-        public void update(DemoItem demoItem) {
-            mItem = demoItem;
-            mLabel.setText(mItem.getName());
-        }
-
-        void setSelected(boolean selected) {
-            mContainer.setActivated(selected);
-            mSelector.setActivated(selected);
-        }
-
-        public String getStableId() {
-            return mItem != null ? mItem.getId() : null;
-        }
-
-        public boolean inDragRegion(MotionEvent e) {
-            // If itemView is activated = selected, then whole region is interactive
-            if (mContainer.isActivated()) {
-                return true;
-            }
-
-            if (inSelectRegion(e)) {
-                return true;
-            }
-
-            Rect rect = new Rect();
-            mLabel.getPaint().getTextBounds(
-                    mLabel.getText().toString(), 0, mLabel.getText().length(), rect);
-
-            // If the tap occurred inside the text, these are interactive spots.
-            return rect.contains((int) e.getRawX(), (int) e.getRawY());
-        }
-
-        public boolean inSelectRegion(MotionEvent e) {
-            Rect iconRect = new Rect();
-            mSelector.getGlobalVisibleRect(iconRect);
-            return iconRect.contains((int) e.getRawX(), (int) e.getRawY());
-        }
-
-        Details getItemDetails() {
-            return mDetails;
-        }
-
-        private static final class Details extends ItemDetails {
-
-            private final DemoHolder mHolder;
-
-            Details(DemoHolder holder) {
-                mHolder = holder;
-            }
-
-            @Override
-            public int getPosition() {
-                return mHolder.getAdapterPosition();
-            }
-
-            @Override
-            public String getStableId() {
-                return mHolder.getStableId();
-            }
-
-            @Override
-            public int getItemViewType() {
-                return mHolder.getItemViewType();
-            }
-
-            @Override
-            public boolean inDragRegion(MotionEvent e) {
-                return mHolder.inDragRegion(e);
-            }
-
-            @Override
-            public boolean inSelectionHotspot(MotionEvent e) {
-                return mHolder.inSelectRegion(e);
-            }
-        }
-    }
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/demo/DemoItem.java b/src/com/android/documentsui/selection/demo/DemoItem.java
deleted file mode 100644
index 15755a0..0000000
--- a/src/com/android/documentsui/selection/demo/DemoItem.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.demo;
-
-public class DemoItem {
-
-    private final String mId;
-    private final String mName;
-
-    DemoItem(String id, String name) {
-        mId = id;
-        mName = name;
-    }
-
-    public String getId() {
-        return mId;
-    }
-
-    public String getName() {
-        return mName;
-    }
-}
diff --git a/src/com/android/documentsui/selection/demo/DemoStableIdProvider.java b/src/com/android/documentsui/selection/demo/DemoStableIdProvider.java
deleted file mode 100644
index 45cdd6c..0000000
--- a/src/com/android/documentsui/selection/demo/DemoStableIdProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.demo;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
-
-import java.util.List;
-
-/**
- * Provides RecyclerView selection code access to stable ids backed
- * by DocumentsAdapter.
- */
-final class DemoStableIdProvider extends StableIdProvider {
-
-    private final SelectionDemoAdapter mAdapter;
-
-    public DemoStableIdProvider(SelectionDemoAdapter adapter) {
-        checkArgument(adapter != null);
-        mAdapter = adapter;
-    }
-
-    @Override
-    public String getStableId(int position) {
-        return mAdapter.getStableId(position);
-    }
-
-    @Override
-    public int getPosition(String id) {
-        return mAdapter.getPosition(id);
-    }
-
-    @Override
-    public List<String> getStableIds() {
-        return mAdapter.getStableIds();
-    }
-}
diff --git a/src/com/android/documentsui/selection/demo/SelectionDemoActivity.java b/src/com/android/documentsui/selection/demo/SelectionDemoActivity.java
deleted file mode 100644
index 6c20695..0000000
--- a/src/com/android/documentsui/selection/demo/SelectionDemoActivity.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.demo;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.annotation.CallSuper;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
-import android.view.GestureDetector;
-import android.view.HapticFeedbackConstants;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.widget.Toast;
-
-import com.android.documentsui.R;
-import com.android.documentsui.selection.BandSelectionHelper;
-import com.android.documentsui.selection.ContentLock;
-import com.android.documentsui.selection.DefaultBandHost;
-import com.android.documentsui.selection.DefaultBandPredicate;
-import com.android.documentsui.selection.DefaultSelectionHelper;
-import com.android.documentsui.selection.GestureRouter;
-import com.android.documentsui.selection.GestureSelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.documentsui.selection.MotionInputHandler;
-import com.android.documentsui.selection.MouseInputHandler;
-import com.android.documentsui.selection.MutableSelection;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
-import com.android.documentsui.selection.TouchEventRouter;
-import com.android.documentsui.selection.TouchInputHandler;
-import com.android.documentsui.selection.demo.SelectionDemoAdapter.OnBindCallback;
-
-/**
- * ContentPager demo activity.
- */
-public class SelectionDemoActivity extends AppCompatActivity {
-
-    private static final String EXTRA_SAVED_SELECTION = "demo-saved-selection";
-    private static final String EXTRA_COLUMN_COUNT = "demo-column-count";
-
-    private Toolbar mToolbar;
-    private SelectionDemoAdapter mAdapter;
-    private SelectionHelper mSelectionHelper;
-
-    private RecyclerView mRecView;
-    private GridLayoutManager mLayout;
-    private int mColumnCount = 1;  // This will get updated when layout changes.
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.selection_demo_layout);
-        mToolbar = findViewById(R.id.toolbar);
-        setSupportActionBar(mToolbar);
-        mRecView = (RecyclerView) findViewById(R.id.list);
-
-        mLayout = new GridLayoutManager(this, mColumnCount);
-        mRecView.setLayoutManager(mLayout);
-
-        mAdapter = new SelectionDemoAdapter(this);
-        mRecView.setAdapter(mAdapter);
-
-        StableIdProvider stableIds = new DemoStableIdProvider(mAdapter);
-
-        // SelectionPredicate permits client control of which items can be selected.
-        SelectionPredicate canSelectAnything = new SelectionPredicate() {
-            @Override
-            public boolean canSetStateForId(String id, boolean nextState) {
-                return true;
-            }
-
-            @Override
-            public boolean canSetStateAtPosition(int position, boolean nextState) {
-                return true;
-            }
-        };
-
-        // TODO: Reload content when it changes. Could use CursorLoader.
-        // TODO: Retain selection. Restore when content changes.
-
-        mSelectionHelper = new DefaultSelectionHelper(
-                DefaultSelectionHelper.MODE_MULTIPLE,
-                mAdapter,
-                stableIds,
-                canSelectAnything);
-
-        // onBind event callback that allows items to be updated to reflect
-        // selection status when bound by recycler view.
-        // This allows us to defer initialization of the SelectionHelper dependency
-        // which itself depends on the Adapter.
-        mAdapter.addOnBindCallback(
-                new OnBindCallback() {
-                    @Override
-                    void onBound(DemoHolder holder, int position) {
-                        String id = mAdapter.getStableId(position);
-                        holder.setSelected(mSelectionHelper.isSelected(id));
-                    }
-                });
-
-        ItemDetailsLookup detailsLookup = new DemoDetailsLookup(mRecView);
-
-        // Setup basic input handling, with the touch handler as the default consumer
-        // of events. If mouse handling is configured as well, the mouse input
-        // related handlers will intercept mouse input events.
-
-        // GestureRouter is responsible for routing GestureDetector events
-        // to tool-type specific handlers.
-        GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>();
-        GestureDetector gestureDetector = new GestureDetector(this, gestureRouter);
-
-        // TouchEventRouter takes its name from RecyclerView#OnItemTouchListener.
-        // Despite "Touch" being in the name, it receives events for all types of tools.
-        // This class is responsible for routing events to tool-type specific handlers,
-        // and if not handled by a handler, on to a GestureDetector for analysis.
-        TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector);
-
-        // Content lock provides a mechanism to block content reload while selection
-        // activities are active. If using a loader to load content, route
-        // the call through the content lock using ContentLock#runWhenUnlocked.
-        // This is especially useful when listening on content change notification.
-        ContentLock contentLock = new ContentLock();
-
-        // GestureSelectionHelper provides logic that interprets a combination
-        // of motions and gestures in order to provide gesture driven selection support
-        // when used in conjunction with RecyclerView.
-        GestureSelectionHelper gestureHelper = GestureSelectionHelper.create(
-                mSelectionHelper, mRecView, contentLock, detailsLookup);
-
-        // Finally hook the framework up to listening to recycle view events.
-        mRecView.addOnItemTouchListener(eventRouter);
-
-        // But before you move on, there's more work to do. Event plumbing has been
-        // installed, but we haven't registered any of our helpers or callbacks.
-        // Helpers contain predefined logic converting events into selection related events.
-        // Callbacks provide authors the ability to reponspond to other types of
-        // events (like "active" a tapped item). This is broken up into two main
-        // suites, one for "touch" and one for "mouse", though both can and should (usually)
-        // be configued to handle other types of input (to satisfy user expectation).
-
-        // TOUCH (+ UNKNOWN) handeling provides gesture based selection allowing
-        // the user to long press on an item, then drag her finger over other
-        // items in order to extend the selection.
-        TouchCallbacks touchCallbacks = new TouchCallbacks(this, mRecView);
-
-        // Provides high level glue for binding touch events and gestures to selection framework.
-        TouchInputHandler touchHandler = new TouchInputHandler(
-                mSelectionHelper, detailsLookup, canSelectAnything, gestureHelper, touchCallbacks);
-
-        eventRouter.register(MotionEvent.TOOL_TYPE_FINGER, gestureHelper);
-        eventRouter.register(MotionEvent.TOOL_TYPE_UNKNOWN, gestureHelper);
-
-        gestureRouter.register(MotionEvent.TOOL_TYPE_FINGER, touchHandler);
-        gestureRouter.register(MotionEvent.TOOL_TYPE_UNKNOWN, touchHandler);
-
-        // MOUSE (+ STYLUS) handeling provides band based selection allowing
-        // the user to click down in an empty area, then drag her mouse
-        // to create a band that covers the items she wants selected.
-        //
-        // PRO TIP: Don't skip installing mouse/stylus support. It provides
-        // improved productivity and demonstrates feature maturity that users
-        // will appreciate. See InputManager for details on more sophisticated
-        // strategies on detecting the presence of input tools.
-
-        // Provides high level glue for binding mouse/stylus events and gestures
-        // to selection framework.
-        MouseInputHandler mouseHandler = new MouseInputHandler(
-                mSelectionHelper, detailsLookup, new MouseCallbacks(this, mRecView));
-
-        DefaultBandHost host = new DefaultBandHost(
-                mRecView, R.drawable.selection_demo_band_overlay);
-
-        // BandSelectionHelper provides support for band selection on-top of a RecyclerView
-        // instance. Given the recycling nature of RecyclerView BandSelectionController
-        // necessarily models and caches list/grid information as the user's pointer
-        // interacts with the item in the RecyclerView. Selectable items that intersect
-        // with the band, both on and off screen, are selected.
-        BandSelectionHelper bandHelper = new BandSelectionHelper(
-                host,
-                mAdapter,
-                stableIds,
-                mSelectionHelper,
-                canSelectAnything,
-                new DefaultBandPredicate(detailsLookup),
-                contentLock);
-
-
-        eventRouter.register(MotionEvent.TOOL_TYPE_MOUSE, bandHelper);
-        eventRouter.register(MotionEvent.TOOL_TYPE_STYLUS, bandHelper);
-
-        gestureRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mouseHandler);
-        gestureRouter.register(MotionEvent.TOOL_TYPE_STYLUS, mouseHandler);
-
-        // Aaaaan, all done with mouse/stylus selection setup!
-
-        updateFromSavedState(savedInstanceState);
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle state) {
-        super.onSaveInstanceState(state);
-        MutableSelection selection = new MutableSelection();
-        mSelectionHelper.copySelection(selection);
-        state.putParcelable(EXTRA_SAVED_SELECTION, selection);
-        state.putInt(EXTRA_COLUMN_COUNT, mColumnCount);
-    }
-
-    private void updateFromSavedState(Bundle state) {
-        // In order to preserve selection across various lifecycle events be sure to save
-        // the selection in onSaveInstanceState, and to restore it when present in the Bundle
-        // pass in via onCreate(Bundle).
-        if (state != null) {
-            if (state.containsKey(EXTRA_SAVED_SELECTION)) {
-                Selection savedSelection = state.getParcelable(EXTRA_SAVED_SELECTION);
-                if (!savedSelection.isEmpty()) {
-                    mSelectionHelper.restoreSelection(savedSelection);
-                    CharSequence text = "Selection restored.";
-                    Toast.makeText(this, "Selection restored.", Toast.LENGTH_SHORT).show();
-                }
-            }
-            if (state.containsKey(EXTRA_COLUMN_COUNT)) {
-                mColumnCount = state.getInt(EXTRA_COLUMN_COUNT);
-                mLayout.setSpanCount(mColumnCount);
-            }
-        }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        boolean showMenu = super.onCreateOptionsMenu(menu);
-        getMenuInflater().inflate(R.menu.selection_demo_actions, menu);
-        return showMenu;
-    }
-
-    @Override
-    @CallSuper
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        super.onPrepareOptionsMenu(menu);
-        menu.findItem(R.id.option_menu_add_column).setEnabled(mColumnCount <= 3);
-        menu.findItem(R.id.option_menu_remove_column).setEnabled(mColumnCount > 1);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.option_menu_add_column:
-                // TODO: Add columns
-                mLayout.setSpanCount(++mColumnCount);
-                return true;
-
-            case R.id.option_menu_remove_column:
-                mLayout.setSpanCount(--mColumnCount);
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-
-    @Override
-    public void onBackPressed () {
-        if (mSelectionHelper.hasSelection()) {
-            mSelectionHelper.clearSelection();
-            mSelectionHelper.clearProvisionalSelection();
-        } else {
-            super.onBackPressed();
-        }
-    }
-
-    private static void toast(Context context, String msg) {
-        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
-    }
-
-    @Override
-    protected void onDestroy() {
-        mSelectionHelper.clearSelection();
-        super.onDestroy();
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        mAdapter.loadData();
-    }
-
-    // Implementation of MouseInputHandler.Callbacks allows handling
-    // of higher level events, like onActivated.
-    private static final class MouseCallbacks extends MouseInputHandler.Callbacks {
-
-        private final Context mContext;
-        private final RecyclerView mRecView;
-
-        MouseCallbacks(Context context, RecyclerView recView) {
-            mContext = context;
-            mRecView = recView;
-        }
-
-        @Override
-        public boolean onItemActivated(ItemDetails item, MotionEvent e) {
-            toast(mContext, "Activate item: " + item.getStableId());
-            return true;
-        }
-
-        @Override
-        public boolean onContextClick(MotionEvent e) {
-            toast(mContext, "Context click received.");
-            return true;
-        }
-
-        @Override
-        public void onPerformHapticFeedback() {
-            mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-        }
-    };
-
-    private static final class TouchCallbacks extends TouchInputHandler.Callbacks {
-
-        private final Context mContext;
-        private final RecyclerView mRecView;
-
-        private TouchCallbacks(Context context, RecyclerView recView) {
-
-            mContext = context;
-            mRecView = recView;
-        }
-
-        @Override
-        public boolean onItemActivated(ItemDetails item, MotionEvent e) {
-            toast(mContext, "Activate item: " + item.getStableId());
-            return true;
-        }
-
-        @Override
-        public void onPerformHapticFeedback() {
-            mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/documentsui/selection/demo/SelectionDemoAdapter.java b/src/com/android/documentsui/selection/demo/SelectionDemoAdapter.java
deleted file mode 100644
index b896e91..0000000
--- a/src/com/android/documentsui/selection/demo/SelectionDemoAdapter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.demo;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import com.android.documentsui.R;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-final class SelectionDemoAdapter extends RecyclerView.Adapter<DemoHolder> {
-
-    private static final Map<String, DemoItem> sDemoData = new HashMap<>();
-    static {
-        for (int i = 0; i < 1000; i++) {
-            String id = createId(i);
-            sDemoData.put(id, new DemoItem(id, "item" + i));
-        }
-    }
-
-    private final Context mContext;
-    private @Nullable OnBindCallback mBindCallback;
-
-    SelectionDemoAdapter(Context context) {
-        mContext = context;
-    }
-
-    void addOnBindCallback(OnBindCallback bindCallback) {
-        mBindCallback = bindCallback;
-    }
-
-    void loadData() {
-        onDataReady();
-    }
-
-    private void onDataReady() {
-        notifyDataSetChanged();
-    }
-
-    @Override
-    public int getItemCount() {
-        return sDemoData.size();
-    }
-
-    @Override
-    public void onBindViewHolder(DemoHolder holder, int position) {
-        String id = createId(position);
-        holder.update(sDemoData.get(id));
-        if (mBindCallback != null) {
-            mBindCallback.onBound(holder, position);
-        }
-    }
-
-    private static String createId(int position) {
-        return "id" + position;
-    }
-
-    @Override
-    public DemoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        LinearLayout layout = inflateLayout(mContext, parent, R.layout.selection_demo_list_item);
-        return new DemoHolder(layout);
-    }
-
-    String getStableId(int position) {
-        return createId(position);
-    }
-
-    int getPosition(String id) {
-        return Integer.parseInt(id.substring(2));
-    }
-
-    List<String> getStableIds() {
-        return new ArrayList<>(sDemoData.keySet());
-    }
-
-    @SuppressWarnings("TypeParameterUnusedInFormals")  // Convenience to avoid clumsy cast.
-    private static <V extends View> V inflateLayout(
-            Context context, ViewGroup parent, int layout) {
-
-        return (V) LayoutInflater.from(context).inflate(layout, parent, false);
-    }
-
-    static abstract class OnBindCallback {
-        abstract void onBound(DemoHolder holder, int position);
-    }
-}
diff --git a/src/com/android/documentsui/services/CopyJob.java b/src/com/android/documentsui/services/CopyJob.java
index b9934dc..5502e0a 100644
--- a/src/com/android/documentsui/services/CopyJob.java
+++ b/src/com/android/documentsui/services/CopyJob.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.services;
 
-import static android.os.SystemClock.elapsedRealtime;
+import static android.content.ContentResolver.wrap;
 import static android.provider.DocumentsContract.buildChildDocumentsUri;
 import static android.provider.DocumentsContract.buildDocumentUri;
 import static android.provider.DocumentsContract.getDocumentId;
@@ -33,7 +33,6 @@
 import static com.android.documentsui.services.FileOperationService.MESSAGE_PROGRESS;
 import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
 
-import android.annotation.StringRes;
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.app.PendingIntent;
@@ -52,6 +51,7 @@
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.storage.StorageManager;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
@@ -59,11 +59,11 @@
 import android.system.Int64Ref;
 import android.system.Os;
 import android.system.OsConstants;
-import android.text.format.DateUtils;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
 import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -73,8 +73,7 @@
 import com.android.documentsui.clipping.UrisSupplier;
 import com.android.documentsui.roots.ProvidersCache;
 import com.android.documentsui.services.FileOperationService.OpType;
-
-import libcore.io.IoUtils;
+import com.android.documentsui.util.FormatUtils;
 
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
@@ -83,6 +82,12 @@
 import java.io.SyncFailedException;
 import java.text.NumberFormat;
 import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Function;
+import java.util.function.LongSupplier;
+
+import androidx.annotation.StringRes;
+import androidx.annotation.VisibleForTesting;
 
 class CopyJob extends ResolvedResourcesJob {
 
@@ -96,15 +101,7 @@
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Messenger mMessenger;
 
-    private long mStartTime = -1;
-    private long mBytesRequired;
-    private volatile long mBytesCopied;
-
-    // Speed estimation.
-    private long mBytesCopiedSample;
-    private long mSampleTime;
-    private long mSpeed;
-    private long mRemainingTime;
+    private CopyJobProgressTracker mProgressTracker;
 
     /**
      * @see @link {@link Job} constructor for most param descriptions.
@@ -138,28 +135,8 @@
     }
 
     Notification getProgressNotification(@StringRes int msgId) {
-        updateRemainingTimeEstimate();
-
-        if (mBytesRequired >= 0) {
-            double completed = (double) this.mBytesCopied / mBytesRequired;
-            mProgressBuilder.setProgress(100, (int) (completed * 100), false);
-            mProgressBuilder.setSubText(
-                    NumberFormat.getPercentInstance().format(completed));
-        } else {
-            // If the total file size failed to compute on some files, then show
-            // an indeterminate spinner. CopyJob would most likely fail on those
-            // files while copying, but would continue with another files.
-            // Also, if the total size is 0 bytes, show an indeterminate spinner.
-            mProgressBuilder.setProgress(0, 0, true);
-        }
-
-        if (mRemainingTime > 0) {
-            mProgressBuilder.setContentText(service.getString(msgId,
-                    DateUtils.formatDuration(mRemainingTime)));
-        } else {
-            mProgressBuilder.setContentText(null);
-        }
-
+        mProgressTracker.update(mProgressBuilder, (remainingTime) -> service.getString(msgId,
+                FormatUtils.formatDuration(remainingTime)));
         return mProgressBuilder.build();
     }
 
@@ -168,10 +145,6 @@
         return getProgressNotification(R.string.copy_remaining);
     }
 
-    void onBytesCopied(long numBytes) {
-        this.mBytesCopied += numBytes;
-    }
-
     @Override
     void finish() {
         try {
@@ -182,33 +155,6 @@
         super.finish();
     }
 
-    /**
-     * Generates an estimate of the remaining time in the copy.
-     */
-    private void updateRemainingTimeEstimate() {
-        long elapsedTime = elapsedRealtime() - mStartTime;
-
-        // mBytesCopied is modified in worker thread, but this method is called in monitor thread,
-        // so take a snapshot of mBytesCopied to make sure the updated estimate is consistent.
-        final long bytesCopied = mBytesCopied;
-        final long sampleDuration = Math.max(elapsedTime - mSampleTime, 1L); // avoid dividing 0
-        final long sampleSpeed = ((bytesCopied - mBytesCopiedSample) * 1000) / sampleDuration;
-        if (mSpeed == 0) {
-            mSpeed = sampleSpeed;
-        } else {
-            mSpeed = ((3 * mSpeed) + sampleSpeed) / 4;
-        }
-
-        if (mSampleTime > 0 && mSpeed > 0) {
-            mRemainingTime = ((mBytesRequired - bytesCopied) * 1000) / mSpeed;
-        } else {
-            mRemainingTime = 0;
-        }
-
-        mSampleTime = elapsedTime;
-        mBytesCopiedSample = bytesCopied;
-    }
-
     @Override
     Notification getFailureNotification() {
         return getFailureNotification(
@@ -248,13 +194,7 @@
         if (isCanceled()) {
             return false;
         }
-
-        try {
-            mBytesRequired = calculateBytesRequired();
-        } catch (ResourceException e) {
-            Log.w(TAG, "Failed to calculate total size. Copying without progress.", e);
-            mBytesRequired = -1;
-        }
+        mProgressTracker = createProgressTracker();
 
         // Check if user has canceled this task. We should check it again here as user cancels
         // tasks in main thread, but this is running in a worker thread. calculateSize() may
@@ -269,14 +209,17 @@
 
     @Override
     void start() {
-        mStartTime = elapsedRealtime();
+        mProgressTracker.start();
+
         DocumentInfo srcInfo;
         for (int i = 0; i < mResolvedDocs.size() && !isCanceled(); ++i) {
             srcInfo = mResolvedDocs.get(i);
 
-            if (DEBUG) Log.d(TAG,
+            if (DEBUG) {
+                Log.d(TAG,
                     "Copying " + srcInfo.displayName + " (" + srcInfo.derivedUri + ")"
-                    + " to " + mDstInfo.displayName + " (" + mDstInfo.derivedUri + ")");
+                        + " to " + mDstInfo.displayName + " (" + mDstInfo.derivedUri + ")");
+            }
 
             try {
                 // Copying recursively to itself or one of descendants is not allowed.
@@ -284,7 +227,7 @@
                     Log.e(TAG, "Skipping recursive copy of " + srcInfo.derivedUri);
                     onFileFailed(srcInfo);
                 } else {
-                    processDocument(srcInfo, null, mDstInfo);
+                    processDocumentThenUpdateProgress(srcInfo, null, mDstInfo);
                 }
             } catch (ResourceException e) {
                 Log.e(TAG, "Failed to copy " + srcInfo.derivedUri, e);
@@ -292,7 +235,7 @@
             }
         }
 
-        Metrics.logFileOperation(service, operationType, mResolvedDocs, mDstInfo);
+        Metrics.logFileOperation(operationType, mResolvedDocs, mDstInfo);
     }
 
     /**
@@ -300,7 +243,15 @@
      * @return true if the root has enough space or doesn't provide free space info; otherwise false
      */
     boolean checkSpace() {
-        return verifySpaceAvailable(mBytesRequired);
+        if (!mProgressTracker.hasRequiredBytes()) {
+            if (DEBUG) {
+                Log.w(TAG,
+                    "Proceeding copy without knowing required space, files or directories may "
+                        + "empty or failed to compute required bytes.");
+            }
+            return true;
+        }
+        return verifySpaceAvailable(mProgressTracker.getRequiredBytes());
     }
 
     /**
@@ -345,15 +296,14 @@
      * @param bytesCopied
      */
     private void makeCopyProgress(long bytesCopied) {
-        final int completed =
-            mBytesRequired >= 0 ? (int) (100.0 * this.mBytesCopied / mBytesRequired) : -1;
         try {
             mMessenger.send(Message.obtain(mHandler, MESSAGE_PROGRESS,
-                    completed, (int) mRemainingTime));
+                    (int) (100 * mProgressTracker.getProgress()), // Progress in percentage
+                    (int) mProgressTracker.getRemainingTimeEstimate()));
         } catch (RemoteException e) {
             // Ignore. The frontend may be gone.
         }
-        onBytesCopied(bytesCopied);
+        mProgressTracker.onBytesCopied(bytesCopied);
     }
 
     /**
@@ -377,21 +327,22 @@
         if (src.authority.equals(dstDirInfo.authority)) {
             if ((src.flags & Document.FLAG_SUPPORTS_COPY) != 0) {
                 try {
-                    if (DocumentsContract.copyDocument(getClient(src), src.derivedUri,
+                    if (DocumentsContract.copyDocument(wrap(getClient(src)), src.derivedUri,
                             dstDirInfo.derivedUri) != null) {
-                        Metrics.logFileOperated(
-                                appContext, operationType, Metrics.OPMODE_PROVIDER);
+                        Metrics.logFileOperated(operationType, MetricConsts.OPMODE_PROVIDER);
                         return;
                     }
-                } catch (RemoteException | RuntimeException e) {
+                } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Log.e(TAG, "Provider side copy failed for: " + src.derivedUri
                             + " due to an exception.", e);
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_QUICK_COPY, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_QUICK_COPY, src.derivedUri);
                 }
 
                 // If optimized copy fails, then fallback to byte-by-byte copy.
-                if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte copy for: " + src.derivedUri);
+                if (DEBUG) {
+                    Log.d(TAG, "Fallback to byte-by-byte copy for: " + src.derivedUri);
+                }
             }
         }
 
@@ -399,11 +350,19 @@
         byteCopyDocument(src, dstDirInfo);
     }
 
+    private void processDocumentThenUpdateProgress(DocumentInfo src, DocumentInfo srcParent,
+            DocumentInfo dstDirInfo) throws ResourceException {
+        processDocument(src, srcParent, dstDirInfo);
+        mProgressTracker.onDocumentCompleted();
+    }
+
     void byteCopyDocument(DocumentInfo src, DocumentInfo dest) throws ResourceException {
         final String dstMimeType;
         final String dstDisplayName;
 
-        if (DEBUG) Log.d(TAG, "Doing byte copy of document: " + src);
+        if (DEBUG) {
+            Log.d(TAG, "Doing byte copy of document: " + src);
+        }
         // If the file is virtual, but can be converted to another format, then try to copy it
         // as such format. Also, append an extension for the target mime type (if known).
         if (src.isVirtual()) {
@@ -412,7 +371,7 @@
                 streamTypes = getContentResolver().getStreamTypes(src.derivedUri, "*/*");
             } catch (RuntimeException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
                 throw new ResourceException(
                         "Failed to obtain streamable types for %s due to an exception.",
                         src.derivedUri, e);
@@ -425,7 +384,7 @@
                         (extension != null ? "." + extension : src.displayName);
             } else {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_OBTAIN_STREAM_TYPE, src.derivedUri);
                 throw new ResourceException("Cannot copy virtual file %s. No streamable formats "
                         + "available.", src.derivedUri);
             }
@@ -439,10 +398,10 @@
         Uri dstUri = null;
         try {
             dstUri = DocumentsContract.createDocument(
-                    getClient(dest), dest.derivedUri, dstMimeType, dstDisplayName);
-        } catch (RemoteException | RuntimeException e) {
+                    wrap(getClient(dest)), dest.derivedUri, dstMimeType, dstDisplayName);
+        } catch (FileNotFoundException | RemoteException | RuntimeException e) {
             Metrics.logFileOperationFailure(
-                    appContext, Metrics.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
+                    appContext, MetricConsts.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
             throw new ResourceException(
                     "Couldn't create destination document " + dstDisplayName + " in directory %s "
                     + "due to an exception.", dest.derivedUri, e);
@@ -450,7 +409,7 @@
         if (dstUri == null) {
             // If this is a directory, the entire subdir will not be copied over.
             Metrics.logFileOperationFailure(
-                    appContext, Metrics.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
+                    appContext, MetricConsts.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
             throw new ResourceException(
                     "Couldn't create destination document " + dstDisplayName + " in directory %s.",
                     dest.derivedUri);
@@ -461,7 +420,7 @@
             dstInfo = DocumentInfo.fromUri(getContentResolver(), dstUri);
         } catch (FileNotFoundException | RuntimeException e) {
             Metrics.logFileOperationFailure(
-                    appContext, Metrics.SUBFILEOP_QUERY_DOCUMENT, dstUri);
+                    appContext, MetricConsts.SUBFILEOP_QUERY_DOCUMENT, dstUri);
             throw new ResourceException("Could not load DocumentInfo for newly created file %s.",
                     dstUri);
         }
@@ -500,7 +459,7 @@
                 cursor = queryChildren(srcDir, queryColumns);
             } catch (RemoteException | RuntimeException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_QUERY_CHILDREN, srcDir.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_QUERY_CHILDREN, srcDir.derivedUri);
                 throw new ResourceException("Failed to query children of %s due to an exception.",
                         srcDir.derivedUri, e);
             }
@@ -523,7 +482,7 @@
                     srcDir.derivedUri.toString(), destDir.derivedUri.toString()), e);
             success = false;
         } finally {
-            IoUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(cursor);
         }
 
         if (!success) {
@@ -559,7 +518,7 @@
                                 src.derivedUri, mimeType, null, mSignal);
                 } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_OPEN_FILE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                     throw new ResourceException("Failed to open a file as asset for %s due to an "
                             + "exception.", src.derivedUri, e);
                 }
@@ -568,33 +527,31 @@
                     in = new AssetFileDescriptor.AutoCloseInputStream(srcFileAsAsset);
                 } catch (IOException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_OPEN_FILE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                     throw new ResourceException("Failed to open a file input stream for %s due "
                             + "an exception.", src.derivedUri, e);
                 }
 
-                Metrics.logFileOperated(
-                        appContext, operationType, Metrics.OPMODE_CONVERTED);
+                Metrics.logFileOperated(operationType, MetricConsts.OPMODE_CONVERTED);
             } else {
                 try {
                     srcFile = getClient(src).openFile(src.derivedUri, "r", mSignal);
                 } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_OPEN_FILE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                     throw new ResourceException(
                             "Failed to open a file for %s due to an exception.", src.derivedUri, e);
                 }
                 in = new ParcelFileDescriptor.AutoCloseInputStream(srcFile);
 
-                Metrics.logFileOperated(
-                        appContext, operationType, Metrics.OPMODE_CONVENTIONAL);
+                Metrics.logFileOperated(operationType, MetricConsts.OPMODE_CONVENTIONAL);
             }
 
             try {
                 dstFile = getClient(dest).openFile(dest.derivedUri, "w", mSignal);
             } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_OPEN_FILE, dest.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_OPEN_FILE, dest.derivedUri);
                 throw new ResourceException("Failed to open the destination file %s for writing "
                         + "due to an exception.", dest.derivedUri, e);
             }
@@ -614,13 +571,15 @@
 
                 try {
                     final Int64Ref last = new Int64Ref(0);
-                    FileUtils.copy(in, out, (long progress) -> {
+                    FileUtils.copy(in, out, mSignal, Runnable::run, (long progress) -> {
                         final long delta = progress - last.value;
                         last.value = progress;
                         makeCopyProgress(delta);
-                    }, mSignal);
+                    });
                 } catch (OperationCanceledException e) {
-                    if (DEBUG) Log.d(TAG, "Canceled copy mid-copy of: " + src.derivedUri);
+                    if (DEBUG) {
+                        Log.d(TAG, "Canceled copy mid-copy of: " + src.derivedUri);
+                    }
                     return;
                 }
 
@@ -636,12 +595,16 @@
                 }
 
                 // Need to invoke IoUtils.close explicitly to avoid from ignoring errors at flush.
-                IoUtils.close(dstFile.getFileDescriptor());
+                try {
+                    Os.close(dstFile.getFileDescriptor());
+                } catch (ErrnoException e) {
+                    throw new IOException(e);
+                }
                 srcFile.checkError();
             } catch (IOException e) {
                 Metrics.logFileOperationFailure(
                         appContext,
-                        Metrics.SUBFILEOP_WRITE_FILE,
+                        MetricConsts.SUBFILEOP_WRITE_FILE,
                         dest.derivedUri);
                 throw new ResourceException(
                         "Failed to copy bytes from %s to %s due to an IO exception.",
@@ -663,7 +626,9 @@
                     }
                 }
 
-                if (DEBUG) Log.d(TAG, "Cleaning up failed operation leftovers.");
+                if (DEBUG) {
+                    Log.d(TAG, "Cleaning up failed operation leftovers.");
+                }
                 mSignal.cancel();
                 try {
                     deleteDocument(dest, destParent);
@@ -673,39 +638,49 @@
             }
 
             // This also ensures the file descriptors are closed.
-            IoUtils.closeQuietly(in);
-            IoUtils.closeQuietly(out);
+            FileUtils.closeQuietly(in);
+            FileUtils.closeQuietly(out);
         }
     }
 
     /**
-     * Calculates the cumulative size of all the documents in the list. Directories are recursed
-     * into and totaled up.
+     * Create CopyJobProgressTracker instance for notification to update copy progress.
      *
-     * @return Size in bytes.
-     * @throws ResourceException
+     * @return Instance of CopyJobProgressTracker according required bytes or documents.
      */
-    private long calculateBytesRequired() throws ResourceException {
-        long result = 0;
+    private CopyJobProgressTracker createProgressTracker() {
+        long docsRequired = mResolvedDocs.size();
+        long bytesRequired = 0;
 
-        for (DocumentInfo src : mResolvedDocs) {
-            if (src.isDirectory()) {
-                // Directories need to be recursed into.
-                try {
-                    result += calculateFileSizesRecursively(getClient(src), src.derivedUri);
-                } catch (RemoteException e) {
-                    throw new ResourceException("Failed to obtain the client for %s.",
-                            src.derivedUri, e);
+        try {
+            for (DocumentInfo src : mResolvedDocs) {
+                if (src.isDirectory()) {
+                    // Directories need to be recursed into.
+                    try {
+                        bytesRequired +=
+                                calculateFileSizesRecursively(getClient(src), src.derivedUri);
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to obtain the client for " + src.derivedUri, e);
+                        return new IndeterminateProgressTracker(bytesRequired);
+                    }
+                } else {
+                    bytesRequired += src.size;
                 }
-            } else {
-                result += src.size;
-            }
 
-            if (isCanceled()) {
-                return result;
+                if (isCanceled()) {
+                    break;
+                }
             }
+        } catch (ResourceException e) {
+            Log.w(TAG, "Failed to calculate total size. Copying without progress.", e);
+            return new IndeterminateProgressTracker(bytesRequired);
         }
-        return result;
+
+        if (bytesRequired > 0) {
+            return new ByteCountProgressTracker(bytesRequired, SystemClock::elapsedRealtime);
+        } else {
+            return new FileCountProgressTracker(docsRequired, SystemClock::elapsedRealtime);
+        }
     }
 
     /**
@@ -743,7 +718,7 @@
             throw new ResourceException(
                     "Failed to calculate size for %s due to an exception.", uri, e);
         } finally {
-            IoUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(cursor);
         }
 
         return result;
@@ -818,8 +793,8 @@
             throws ResourceException {
         if (parent.isDirectory() && doc.authority.equals(parent.authority)) {
             try {
-                return isChildDocument(getClient(doc), doc.derivedUri, parent.derivedUri);
-            } catch (RemoteException | RuntimeException e) {
+                return isChildDocument(wrap(getClient(doc)), doc.derivedUri, parent.derivedUri);
+            } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                 throw new ResourceException(
                         "Failed to check if %s is a child of %s due to an exception.",
                         doc.derivedUri, parent.derivedUri, e);
@@ -858,4 +833,157 @@
             }
         }
     }
+
+    @VisibleForTesting
+    static abstract class CopyJobProgressTracker implements ProgressTracker {
+        private LongSupplier mElapsedRealTimeSupplier;
+        // Speed estimation.
+        private long mStartTime = -1;
+        private long mDataProcessedSample;
+        private long mSampleTime;
+        private long mSpeed;
+        private long mRemainingTime = -1;
+
+        public CopyJobProgressTracker(LongSupplier timeSupplier) {
+            mElapsedRealTimeSupplier = timeSupplier;
+        }
+
+        protected void onBytesCopied(long numBytes) {
+        }
+
+        protected void onDocumentCompleted() {
+        }
+
+        protected boolean hasRequiredBytes() {
+            return false;
+        }
+
+        protected long getRequiredBytes() {
+            return -1;
+        }
+
+        protected void start() {
+            mStartTime = mElapsedRealTimeSupplier.getAsLong();
+        }
+
+        protected void update(Builder builder, Function<Long, String> messageFormatter) {
+            updateEstimateRemainingTime();
+            final double completed = getProgress();
+
+            builder.setProgress(100, (int) (completed * 100), false);
+            builder.setSubText(
+                    NumberFormat.getPercentInstance().format(completed));
+            if (getRemainingTimeEstimate() > 0) {
+                builder.setContentText(messageFormatter.apply(getRemainingTimeEstimate()));
+            } else {
+                builder.setContentText(null);
+            }
+        }
+
+        abstract void updateEstimateRemainingTime();
+
+        /**
+         * Generates an estimate of the remaining time in the copy.
+         * @param dataProcessed the number of data processed
+         * @param dataRequired the number of data required.
+         */
+        protected void estimateRemainingTime(final long dataProcessed, final long dataRequired) {
+            final long currentTime = mElapsedRealTimeSupplier.getAsLong();
+            final long elapsedTime = currentTime - mStartTime;
+            final long sampleDuration = Math.max(elapsedTime - mSampleTime, 1L); // avoid dividing 0
+            final long sampleSpeed =
+                    ((dataProcessed - mDataProcessedSample) * 1000) / sampleDuration;
+            if (mSpeed == 0) {
+                mSpeed = sampleSpeed;
+            } else {
+                mSpeed = ((3 * mSpeed) + sampleSpeed) / 4;
+            }
+
+            if (mSampleTime > 0 && mSpeed > 0) {
+                mRemainingTime = ((dataRequired - dataProcessed) * 1000) / mSpeed;
+            }
+
+            mSampleTime = elapsedTime;
+            mDataProcessedSample = dataProcessed;
+        }
+
+        @Override
+        public long getRemainingTimeEstimate() {
+            return mRemainingTime;
+        }
+    }
+
+    @VisibleForTesting
+    static class ByteCountProgressTracker extends CopyJobProgressTracker {
+        final long mBytesRequired;
+        final AtomicLong mBytesCopied = new AtomicLong(0);
+
+        public ByteCountProgressTracker(long bytesRequired, LongSupplier elapsedRealtimeSupplier) {
+            super(elapsedRealtimeSupplier);
+            mBytesRequired = bytesRequired;
+        }
+
+        @Override
+        public double getProgress() {
+            return (double) mBytesCopied.get() / mBytesRequired;
+        }
+
+        @Override
+        protected boolean hasRequiredBytes() {
+            return mBytesRequired > 0;
+        }
+
+        @Override
+        public void onBytesCopied(long numBytes) {
+            mBytesCopied.getAndAdd(numBytes);
+        }
+
+        @Override
+        public void updateEstimateRemainingTime() {
+            estimateRemainingTime(mBytesCopied.get(), mBytesRequired);
+        }
+    }
+
+    @VisibleForTesting
+    static class FileCountProgressTracker extends CopyJobProgressTracker {
+        final long mDocsRequired;
+        final AtomicLong mDocsProcessed = new AtomicLong(0);
+
+        public FileCountProgressTracker(long docsRequired, LongSupplier elapsedRealtimeSupplier) {
+            super(elapsedRealtimeSupplier);
+            mDocsRequired = docsRequired;
+        }
+
+        @Override
+        public double getProgress() {
+            // Use the number of copied docs to calculate progress when mBytesRequired is zero.
+            return (double) mDocsProcessed.get() / mDocsRequired;
+        }
+
+        @Override
+        public void onDocumentCompleted() {
+            mDocsProcessed.getAndIncrement();
+        }
+
+        @Override
+        public void updateEstimateRemainingTime() {
+            estimateRemainingTime(mDocsProcessed.get(), mDocsRequired);
+        }
+    }
+
+    private static class IndeterminateProgressTracker extends ByteCountProgressTracker {
+        public IndeterminateProgressTracker(long bytesRequired) {
+            super(bytesRequired, () -> -1L /* No need to update elapsedTime */);
+        }
+
+        @Override
+        protected void update(Builder builder, Function<Long, String> messageFormatter) {
+            // If the total file size failed to compute on some files, then show
+            // an indeterminate spinner. CopyJob would most likely fail on those
+            // files while copying, but would continue with another files.
+            // Also, if the total size is 0 bytes, show an indeterminate spinner.
+            builder.setProgress(0, 0, true);
+            builder.setContentText(null);
+        }
+    }
 }
diff --git a/src/com/android/documentsui/services/DeleteJob.java b/src/com/android/documentsui/services/DeleteJob.java
index 041eba7..38b8288 100644
--- a/src/com/android/documentsui/services/DeleteJob.java
+++ b/src/com/android/documentsui/services/DeleteJob.java
@@ -26,6 +26,7 @@
 import android.net.Uri;
 import android.util.Log;
 
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -44,6 +45,7 @@
     private final Uri mParentUri;
 
     private volatile int mDocsProcessed = 0;
+
     /**
      * Moves files to a destination identified by {@code destination}.
      * Performs most work by delegating to CopyJob, then deleting
@@ -110,12 +112,14 @@
         }
 
         for (DocumentInfo doc : mResolvedDocs) {
-            if (DEBUG) Log.d(TAG, "Deleting document @ " + doc.derivedUri);
+            if (DEBUG) {
+                Log.d(TAG, "Deleting document @ " + doc.derivedUri);
+            }
             try {
                 deleteDocument(doc, parentDoc);
             } catch (ResourceException e) {
                 Metrics.logFileOperationFailure(
-                        appContext, Metrics.SUBFILEOP_DELETE_DOCUMENT, doc.derivedUri);
+                        appContext, MetricConsts.SUBFILEOP_DELETE_DOCUMENT, doc.derivedUri);
                 Log.e(TAG, "Failed to delete document @ " + doc.derivedUri, e);
                 onFileFailed(doc);
             }
@@ -126,7 +130,7 @@
             }
         }
 
-        Metrics.logFileOperation(service, operationType, mResolvedDocs, null);
+        Metrics.logFileOperation(operationType, mResolvedDocs, null);
     }
 
     @Override
diff --git a/src/com/android/documentsui/services/FileOperation.java b/src/com/android/documentsui/services/FileOperation.java
index 1f0e9b9..29393a8 100644
--- a/src/com/android/documentsui/services/FileOperation.java
+++ b/src/com/android/documentsui/services/FileOperation.java
@@ -22,7 +22,7 @@
 import static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT;
 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
 import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
-import static com.android.internal.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 
 import android.content.Context;
 import android.net.Uri;
@@ -32,7 +32,7 @@
 import android.os.Messenger;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.Features;
diff --git a/src/com/android/documentsui/services/FileOperationService.java b/src/com/android/documentsui/services/FileOperationService.java
index fa97ebf..ca6166a 100644
--- a/src/com/android/documentsui/services/FileOperationService.java
+++ b/src/com/android/documentsui/services/FileOperationService.java
@@ -18,17 +18,18 @@
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.util.Log;
 
 import com.android.documentsui.R;
@@ -158,10 +159,13 @@
             notificationManager = getSystemService(NotificationManager.class);
         }
 
-        features = new Features.RuntimeFeatures(getResources(), UserManager.get(this));
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        features = new Features.RuntimeFeatures(getResources(), userManager);
         setUpNotificationChannel();
 
-        if (DEBUG) Log.d(TAG, "Created.");
+        if (DEBUG) {
+            Log.d(TAG, "Created.");
+        }
         mPowerManager = getSystemService(PowerManager.class);
     }
 
@@ -177,7 +181,9 @@
 
     @Override
     public void onDestroy() {
-        if (DEBUG) Log.d(TAG, "Shutting down executor.");
+        if (DEBUG) {
+            Log.d(TAG, "Shutting down executor.");
+        }
 
         List<Runnable> unfinishedCopies = executor.shutdownNow();
         List<Runnable> unfinishedDeletions = deletionExecutor.shutdownNow();
@@ -193,7 +199,9 @@
         deletionExecutor = null;
         handler = null;
 
-        if (DEBUG) Log.d(TAG, "Destroyed.");
+        if (DEBUG) {
+            Log.d(TAG, "Destroyed.");
+        }
     }
 
     @Override
@@ -204,7 +212,9 @@
         String jobId = intent.getStringExtra(EXTRA_JOB_ID);
         assert(jobId != null);
 
-        if (DEBUG) Log.d(TAG, "onStartCommand: " + jobId + " with serviceId " + serviceId);
+        if (DEBUG) {
+            Log.d(TAG, "onStartCommand: " + jobId + " with serviceId " + serviceId);
+        }
 
         if (intent.hasExtra(EXTRA_CANCEL)) {
             handleCancel(intent);
@@ -238,7 +248,9 @@
             }
 
             assert (job != null);
-            if (DEBUG) Log.d(TAG, "Scheduling job " + job.id + ".");
+            if (DEBUG) {
+                Log.d(TAG, "Scheduling job " + job.id + ".");
+            }
             Future<?> future = getExecutorService(operation.getOpType()).submit(job);
             mJobs.put(jobId, new JobRecord(job, future));
 
@@ -260,7 +272,9 @@
 
         String jobId = intent.getStringExtra(EXTRA_JOB_ID);
 
-        if (DEBUG) Log.d(TAG, "handleCancel: " + jobId);
+        if (DEBUG) {
+            Log.d(TAG, "handleCancel: " + jobId);
+        }
 
         synchronized (mJobs) {
             // Do nothing if the cancelled ID doesn't match the current job ID. This prevents racey
@@ -299,7 +313,9 @@
 
     @GuardedBy("mJobs")
     private void deleteJob(Job job) {
-        if (DEBUG) Log.d(TAG, "deleteJob: " + job.id);
+        if (DEBUG) {
+            Log.d(TAG, "deleteJob: " + job.id);
+        }
 
         // Release wake lock before clearing jobs just in case we fail to clean them up.
         mWakeLock.release();
@@ -320,14 +336,18 @@
      * message. Thread pool is deal with in onDestroy.
      */
     private void shutdown() {
-        if (DEBUG) Log.d(TAG, "Shutting down. Last serviceId was " + mLastServiceId);
+        if (DEBUG) {
+            Log.d(TAG, "Shutting down. Last serviceId was " + mLastServiceId);
+        }
         assert(mWakeLock == null);
 
         // Turns out, for us, stopSelfResult always returns false in tests,
         // so we can't guard executor shutdown. For this reason we move
         // executor shutdown to #onDestroy.
         boolean gonnaStop = stopSelfResult(mLastServiceId);
-        if (DEBUG) Log.d(TAG, "Stopping service: " + gonnaStop);
+        if (DEBUG) {
+            Log.d(TAG, "Stopping service: " + gonnaStop);
+        }
         if (!gonnaStop) {
             Log.w(TAG, "Service should be stopping, but reports otherwise.");
         }
@@ -340,18 +360,24 @@
 
     @Override
     public void onStart(Job job) {
-        if (DEBUG) Log.d(TAG, "onStart: " + job.id);
+        if (DEBUG) {
+            Log.d(TAG, "onStart: " + job.id);
+        }
 
         Notification notification = job.getSetupNotification();
         // If there is no foreground job yet, set this job to foreground job.
         synchronized (mJobs) {
             if (mForegroundJob == null) {
-                if (DEBUG) Log.d(TAG, "Set foreground job to " + job.id);
+                if (DEBUG) {
+                    Log.d(TAG, "Set foreground job to " + job.id);
+                }
                 mForegroundJob = job;
                 foregroundManager.startForeground(NOTIFICATION_ID_PROGRESS, notification);
             } else {
                 // Show start up notification
-                if (DEBUG) Log.d(TAG, "Posting notification for " + job.id);
+                if (DEBUG) {
+                    Log.d(TAG, "Posting notification for " + job.id);
+                }
                 notificationManager.notify(
                         mForegroundJob == job ? null : job.id,
                         NOTIFICATION_ID_PROGRESS,
@@ -367,7 +393,9 @@
     @Override
     public void onFinished(Job job) {
         assert(job.isFinished());
-        if (DEBUG) Log.d(TAG, "onFinished: " + job.id);
+        if (DEBUG) {
+            Log.d(TAG, "onFinished: " + job.id);
+        }
 
         synchronized (mJobs) {
             // Delete the job from mJobs first to avoid this job being selected as the foreground
@@ -401,12 +429,16 @@
         if (mForegroundJob == job) {
             mForegroundJob = candidate;
             if (candidate == null) {
-                if (DEBUG) Log.d(TAG, "Stop foreground");
+                if (DEBUG) {
+                    Log.d(TAG, "Stop foreground");
+                }
                 // Remove the notification here just in case we're torn down before we have the
                 // chance to clean up notifications.
                 foregroundManager.stopForeground(true);
             } else {
-                if (DEBUG) Log.d(TAG, "Switch foreground job to " + candidate.id);
+                if (DEBUG) {
+                    Log.d(TAG, "Switch foreground job to " + candidate.id);
+                }
 
                 notificationManager.cancel(candidate.id, NOTIFICATION_ID_PROGRESS);
                 Notification notification = (candidate.getState() == Job.STATE_STARTED)
@@ -419,7 +451,9 @@
 
     private void cleanUpNotification(Job job) {
 
-        if (DEBUG) Log.d(TAG, "Canceling notification for " + job.id);
+        if (DEBUG) {
+            Log.d(TAG, "Canceling notification for " + job.id);
+        }
         // Dismiss the ongoing copy notification when the copy is done.
         notificationManager.cancel(job.id, NOTIFICATION_ID_PROGRESS);
 
@@ -435,7 +469,9 @@
         }
 
         if (job.hasWarnings()) {
-            if (DEBUG) Log.d(TAG, "Job finished with warnings.");
+            if (DEBUG) {
+                Log.d(TAG, "Job finished with warnings.");
+            }
             notificationManager.notify(
                     job.id, NOTIFICATION_ID_WARNING, job.getWarningNotification());
         }
diff --git a/src/com/android/documentsui/services/FileOperations.java b/src/com/android/documentsui/services/FileOperations.java
index d35b237..e8a2c35 100644
--- a/src/com/android/documentsui/services/FileOperations.java
+++ b/src/com/android/documentsui/services/FileOperations.java
@@ -22,11 +22,11 @@
 import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID;
 import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.util.Log;
 
 import com.android.documentsui.services.FileOperationService.OpType;
@@ -58,13 +58,16 @@
     public static String start(Context context, FileOperation operation, Callback callback,
             @Nullable String jobId) {
 
-        if (DEBUG) Log.d(TAG, "Handling generic 'start' call.");
+        if (DEBUG) {
+            Log.d(TAG, "Handling generic 'start' call.");
+        }
 
         String newJobId = jobId != null ? jobId : createJobId();
         Intent intent = createBaseIntent(context, newJobId, operation);
-
-        callback.onOperationResult(Callback.STATUS_ACCEPTED, operation.getOpType(),
-                operation.getSrc().getItemCount());
+        if (callback != null) {
+            callback.onOperationResult(Callback.STATUS_ACCEPTED, operation.getOpType(),
+                    operation.getSrc().getItemCount());
+        }
 
         context.startService(intent);
 
@@ -73,7 +76,9 @@
 
     @VisibleForTesting
     public static void cancel(Activity activity, String jobId) {
-        if (DEBUG) Log.d(TAG, "Attempting to canceling operation: " + jobId);
+        if (DEBUG) {
+            Log.d(TAG, "Attempting to canceling operation: " + jobId);
+        }
 
         Intent intent = new Intent(activity, FileOperationService.class);
         intent.putExtra(EXTRA_CANCEL, true);
diff --git a/src/com/android/documentsui/services/Job.java b/src/com/android/documentsui/services/Job.java
index 67b8df3..b6f83df 100644
--- a/src/com/android/documentsui/services/Job.java
+++ b/src/com/android/documentsui/services/Job.java
@@ -16,6 +16,8 @@
 
 package com.android.documentsui.services;
 
+import static android.content.ContentResolver.wrap;
+
 import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
 import static com.android.documentsui.services.FileOperationService.EXTRA_CANCEL;
 import static com.android.documentsui.services.FileOperationService.EXTRA_DIALOG_TYPE;
@@ -25,9 +27,9 @@
 import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION_TYPE;
 import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
 
-import android.annotation.DrawableRes;
-import android.annotation.IntDef;
-import android.annotation.PluralsRes;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
+import androidx.annotation.PluralsRes;
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.app.PendingIntent;
@@ -37,6 +39,7 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.CancellationSignal;
+import android.os.FileUtils;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
@@ -53,6 +56,7 @@
 import com.android.documentsui.files.FilesActivity;
 import com.android.documentsui.services.FileOperationService.OpType;
 
+import java.io.FileNotFoundException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -159,7 +163,7 @@
             // No exceptions should be thrown here, as all calls to the provider must be
             // handled within Job implementations. However, just in case catch them here.
             Log.e(TAG, "Operation failed due to an unhandled runtime exception.", e);
-            Metrics.logFileOperationErrors(service, operationType, failedDocs, failedUris);
+            Metrics.logFileOperationErrors(operationType, failedDocs, failedUris);
         } finally {
             mState = (mState == STATE_STARTED || mState == STATE_SET_UP) ? STATE_COMPLETED : mState;
             finish();
@@ -209,7 +213,7 @@
 
     final void cleanup() {
         for (ContentProviderClient client : mClients.values()) {
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(client);
         }
     }
 
@@ -220,7 +224,7 @@
     final void cancel() {
         mState = STATE_CANCELED;
         mSignal.cancel();
-        Metrics.logFileOperationCancelled(service, operationType);
+        Metrics.logFileOperationCancelled(operationType);
     }
 
     final boolean isCanceled() {
@@ -257,14 +261,15 @@
             throws ResourceException {
         try {
             if (parent != null && doc.isRemoveSupported()) {
-                DocumentsContract.removeDocument(getClient(doc), doc.derivedUri, parent.derivedUri);
+                DocumentsContract.removeDocument(wrap(getClient(doc)), doc.derivedUri,
+                        parent.derivedUri);
             } else if (doc.isDeleteSupported()) {
-                DocumentsContract.deleteDocument(getClient(doc), doc.derivedUri);
+                DocumentsContract.deleteDocument(wrap(getClient(doc)), doc.derivedUri);
             } else {
                 throw new ResourceException("Unable to delete source document. "
                         + "File is not deletable or removable: %s.", doc.derivedUri);
             }
-        } catch (RemoteException | RuntimeException e) {
+        } catch (FileNotFoundException | RemoteException | RuntimeException e) {
             throw new ResourceException("Failed to delete file %s due to an exception.",
                     doc.derivedUri, e);
         }
@@ -367,4 +372,14 @@
         void onStart(Job job);
         void onFinished(Job job);
     }
+
+    /**
+     * Interface for tracking job progress.
+     */
+    interface ProgressTracker {
+        default double getProgress() {  return -1; }
+        default long getRemainingTimeEstimate() {
+            return -1;
+        }
+    }
 }
diff --git a/src/com/android/documentsui/services/MoveJob.java b/src/com/android/documentsui/services/MoveJob.java
index c46f39b..faccedb 100644
--- a/src/com/android/documentsui/services/MoveJob.java
+++ b/src/com/android/documentsui/services/MoveJob.java
@@ -16,6 +16,8 @@
 
 package com.android.documentsui.services;
 
+import static android.content.ContentResolver.wrap;
+
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
 
@@ -30,6 +32,7 @@
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -146,21 +149,22 @@
         if (src.authority.equals(dest.authority) && (srcParent != null || mSrcParent != null)) {
             if ((src.flags & Document.FLAG_SUPPORTS_MOVE) != 0) {
                 try {
-                    if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
+                    if (DocumentsContract.moveDocument(wrap(getClient(src)), src.derivedUri,
                             srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri,
                             dest.derivedUri) != null) {
-                        Metrics.logFileOperated(
-                                appContext, operationType, Metrics.OPMODE_PROVIDER);
+                        Metrics.logFileOperated(operationType, MetricConsts.OPMODE_PROVIDER);
                         return;
                     }
-                } catch (RemoteException | RuntimeException e) {
+                } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                     Metrics.logFileOperationFailure(
-                            appContext, Metrics.SUBFILEOP_QUICK_MOVE, src.derivedUri);
+                            appContext, MetricConsts.SUBFILEOP_QUICK_MOVE, src.derivedUri);
                     Log.e(TAG, "Provider side move failed for: " + src.derivedUri
                             + " due to an exception: ", e);
                 }
                 // If optimized move fails, then fallback to byte-by-byte copy.
-                if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte move for: " + src.derivedUri);
+                if (DEBUG) {
+                    Log.d(TAG, "Fallback to byte-by-byte move for: " + src.derivedUri);
+                }
             }
         }
 
diff --git a/src/com/android/documentsui/sidebar/AppItem.java b/src/com/android/documentsui/sidebar/AppItem.java
index 2b74973..8a8756c 100644
--- a/src/com/android/documentsui/sidebar/AppItem.java
+++ b/src/com/android/documentsui/sidebar/AppItem.java
@@ -25,23 +25,23 @@
 import android.widget.TextView;
 
 import com.android.documentsui.ActionHandler;
+import com.android.documentsui.IconUtils;
 import com.android.documentsui.R;
 
 /**
  * An {@link Item} for apps that supports some picking actions like
  * {@link Intent#ACTION_GET_CONTENT} such as Photos. This is only used in pickers.
  */
-class AppItem extends Item {
+public class AppItem extends Item {
     private static final String STRING_ID_FORMAT = "AppItem{%s/%s}";
 
     public final ResolveInfo info;
 
     private final ActionHandler mActionHandler;
 
-    public AppItem(ResolveInfo info, ActionHandler actionHandler) {
-        super(R.layout.item_root, getStringId(info));
+    public AppItem(ResolveInfo info, String title, ActionHandler actionHandler) {
+        super(R.layout.item_root, title, getStringId(info));
         this.info = info;
-
         mActionHandler = actionHandler;
     }
 
@@ -53,6 +53,21 @@
         return component;
     }
 
+    protected void bindIcon(ImageView icon) {
+        final PackageManager pm = icon.getContext().getPackageManager();
+        icon.setImageDrawable(info.loadIcon(pm));
+    }
+
+
+    protected void bindActionIcon(View actionIconArea, ImageView actionIcon) {
+        actionIconArea.setVisibility(View.VISIBLE);
+        actionIconArea.setFocusable(false);
+        actionIcon.setImageDrawable(
+                IconUtils.applyTintColor(actionIcon.getContext(), R.drawable.ic_exit_to_app,
+                        R.color.item_action_icon));
+
+    }
+
     @Override
     boolean showAppDetails() {
         mActionHandler.showAppDetails(info);
@@ -62,12 +77,15 @@
     @Override
     void bindView(View convertView) {
         final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
-        final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+        final TextView titleView = (TextView) convertView.findViewById(android.R.id.title);
         final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+        final View actionIconArea = convertView.findViewById(R.id.action_icon_area);
+        final ImageView actionIcon = (ImageView) convertView.findViewById(R.id.action_icon);
 
-        final PackageManager pm = convertView.getContext().getPackageManager();
-        icon.setImageDrawable(info.loadIcon(pm));
-        title.setText(info.loadLabel(pm));
+        titleView.setText(title);
+
+        bindIcon(icon);
+        bindActionIcon(actionIconArea, actionIcon);
 
         // TODO: match existing summary behavior from disambig dialog
         summary.setVisibility(View.GONE);
@@ -85,6 +103,11 @@
     }
 
     @Override
+    String getPackageName() {
+        return info.activityInfo.packageName;
+    }
+
+    @Override
     public String toString() {
         return "AppItem{"
                 + "id=" + stringId
diff --git a/src/com/android/documentsui/sidebar/DragHost.java b/src/com/android/documentsui/sidebar/DragHost.java
index 6b034df..f784873 100644
--- a/src/com/android/documentsui/sidebar/DragHost.java
+++ b/src/com/android/documentsui/sidebar/DragHost.java
@@ -56,6 +56,11 @@
     }
 
     @Override
+    public boolean canHandleDragEvent(View v) {
+        return v instanceof RootItemView;
+    }
+
+    @Override
     public void setDropTargetHighlight(View v, boolean highlight) {
         // SpacerView doesn't have DragListener so this view is guaranteed to be a RootItemView.
         RootItemView itemView = (RootItemView) v;
diff --git a/src/com/android/documentsui/sidebar/EjectRootTask.java b/src/com/android/documentsui/sidebar/EjectRootTask.java
index 2baeb4c..452eb9d 100644
--- a/src/com/android/documentsui/sidebar/EjectRootTask.java
+++ b/src/com/android/documentsui/sidebar/EjectRootTask.java
@@ -16,10 +16,13 @@
 
 package com.android.documentsui.sidebar;
 
+import static android.content.ContentResolver.wrap;
+
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.FileUtils;
 import android.provider.DocumentsContract;
 import android.util.Log;
 
@@ -57,14 +60,14 @@
         try {
             client = DocumentsApplication.acquireUnstableProviderOrThrow(
                     mResolver, mAuthority);
-            DocumentsContract.ejectRoot(client, rootUri);
+            DocumentsContract.ejectRoot(wrap(client), rootUri);
             return true;
         } catch (IllegalStateException e) {
             Log.w(TAG, "Failed to eject root.", e);
         } catch (Exception e) {
             Log.w(TAG, "Binder call failed.", e);
         } finally {
-            ContentProviderClient.releaseQuietly(client);
+            FileUtils.closeQuietly(client);
         }
 
         return false;
diff --git a/src/com/android/documentsui/sidebar/Item.java b/src/com/android/documentsui/sidebar/Item.java
index fd32a27..8bd1f32 100644
--- a/src/com/android/documentsui/sidebar/Item.java
+++ b/src/com/android/documentsui/sidebar/Item.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.sidebar;
 
-import android.annotation.LayoutRes;
+import androidx.annotation.LayoutRes;
 import android.view.DragEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -31,13 +31,15 @@
  * Describes a root navigation point of documents. Each one of them is presented as an item in the
  * sidebar
  */
-abstract class Item {
+public abstract class Item {
     private final @LayoutRes int mLayoutId;
 
+    public final String title;
     final String stringId;
 
-    public Item(@LayoutRes int layoutId, String stringId) {
+    public Item(@LayoutRes int layoutId, String title, String stringId) {
         mLayoutId = layoutId;
+        this.title = title;
         this.stringId = stringId;
     }
 
@@ -58,6 +60,10 @@
 
     abstract void open();
 
+    String getPackageName() {
+        return "";
+    }
+
     boolean isDropTarget() {
         return isRoot();
     }
diff --git a/src/com/android/documentsui/sidebar/ProfileItem.java b/src/com/android/documentsui/sidebar/ProfileItem.java
new file mode 100644
index 0000000..ca9b69a
--- /dev/null
+++ b/src/com/android/documentsui/sidebar/ProfileItem.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 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.documentsui.sidebar;
+
+import android.content.pm.ResolveInfo;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.documentsui.ActionHandler;
+
+/**
+ * An {@link Item} for switch profile. This is only used in pickers.
+ */
+class ProfileItem extends AppItem {
+
+    public ProfileItem(ResolveInfo info, String title, ActionHandler actionHandler) {
+        super(info, title, actionHandler);
+    }
+
+    @Override
+    protected void bindIcon(ImageView icon) {
+        icon.setImageResource(com.android.documentsui.R.drawable.ic_user_profile);
+    }
+
+    @Override
+    protected void bindActionIcon(View actionIconArea, ImageView actionIcon) {
+        actionIconArea.setVisibility(View.GONE);
+    }
+
+    @Override
+    public String toString() {
+        return "ProfileItem{"
+                + "id=" + stringId
+                + ", resolveInfo=" + info
+                + "}";
+    }
+}
diff --git a/src/com/android/documentsui/sidebar/RootAndAppItem.java b/src/com/android/documentsui/sidebar/RootAndAppItem.java
new file mode 100644
index 0000000..65bed6e
--- /dev/null
+++ b/src/com/android/documentsui/sidebar/RootAndAppItem.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 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.documentsui.sidebar;
+
+import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.provider.DocumentsProvider;
+import android.view.View;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.R;
+import com.android.documentsui.base.RootInfo;
+
+/**
+ * An {@link Item} for each root provided by {@link DocumentsProvider}s
+ * and apps that supports some picking actions like {@link Intent#ACTION_GET_CONTENT}.
+ * This is only used in pickers.
+ */
+class RootAndAppItem extends RootItem {
+
+    public final ResolveInfo resolveInfo;
+
+    public RootAndAppItem(RootInfo root, ResolveInfo info, ActionHandler actionHandler) {
+        super(root, actionHandler, info.activityInfo.packageName);
+        this.resolveInfo = info;
+    }
+
+    @Override
+    boolean showAppDetails() {
+        mActionHandler.showAppDetails(resolveInfo);
+        return true;
+    }
+
+    @Override
+    public void bindView(View convertView) {
+        final Context context = convertView.getContext();
+
+        String contentDescription =
+                context.getResources().getString(R.string.open_external_app, root.title);
+
+        bindAction(convertView, View.VISIBLE, R.drawable.ic_exit_to_app, contentDescription);
+        bindIconAndTitle(convertView);
+        bindSummary(convertView, root.summary);
+    }
+
+    @Override
+    protected void onActionClick(View view) {
+        mActionHandler.openRoot(resolveInfo);
+    }
+
+    @Override
+    public String toString() {
+        return "RootAndAppItem{"
+                + "id=" + stringId
+                + ", root=" + root
+                + ", resolveInfo=" + resolveInfo
+                + ", docInfo=" + docInfo
+                + "}";
+    }
+}
diff --git a/src/com/android/documentsui/sidebar/RootItem.java b/src/com/android/documentsui/sidebar/RootItem.java
index 4e27869..774fb08 100644
--- a/src/com/android/documentsui/sidebar/RootItem.java
+++ b/src/com/android/documentsui/sidebar/RootItem.java
@@ -16,8 +16,9 @@
 
 package com.android.documentsui.sidebar;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.provider.DocumentsProvider;
 import android.text.TextUtils;
 import android.text.format.Formatter;
@@ -25,11 +26,11 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.documentsui.ActionHandler;
+import com.android.documentsui.IconUtils;
 import com.android.documentsui.MenuManager;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
@@ -38,18 +39,24 @@
 /**
  * An {@link Item} for each root provided by {@link DocumentsProvider}s.
  */
-class RootItem extends Item {
+public class RootItem extends Item {
     private static final String STRING_ID_FORMAT = "RootItem{%s/%s}";
 
     public final RootInfo root;
     public @Nullable DocumentInfo docInfo;
 
-    private final ActionHandler mActionHandler;
+    protected final ActionHandler mActionHandler;
+    private final String mPackageName;
 
     public RootItem(RootInfo root, ActionHandler actionHandler) {
-        super(R.layout.item_root, getStringId(root));
+        this(root, actionHandler, "" /* packageName */);
+    }
+
+    public RootItem(RootInfo root, ActionHandler actionHandler, String packageName) {
+        super(R.layout.item_root, root.title, getStringId(root));
         this.root = root;
         mActionHandler = actionHandler;
+        mPackageName = packageName;
     }
 
     private static String getStringId(RootInfo root) {
@@ -62,27 +69,12 @@
 
     @Override
     public void bindView(View convertView) {
-        final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
-        final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-        final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
-        final ImageView ejectIcon = (ImageView) convertView.findViewById(R.id.eject_icon);
-
         final Context context = convertView.getContext();
-        icon.setImageDrawable(root.loadDrawerIcon(context));
-        title.setText(root.title);
-
         if (root.supportsEject()) {
-            ejectIcon.setVisibility(View.VISIBLE);
-            ejectIcon.setImageDrawable(root.loadEjectIcon(context));
-            ejectIcon.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View unmountIcon) {
-                    RootsFragment.ejectClicked(unmountIcon, root, mActionHandler);
-                }
-            });
+            bindAction(convertView, View.VISIBLE, R.drawable.ic_eject,
+                    context.getResources().getString(R.string.menu_eject_root));
         } else {
-            ejectIcon.setVisibility(View.GONE);
-            ejectIcon.setOnClickListener(null);
+            bindAction(convertView, View.GONE, -1 /* iconResource */, null /* description */);
         }
         // Show available space if no summary
         String summaryText = root.summary;
@@ -91,8 +83,50 @@
                     Formatter.formatFileSize(context, root.availableBytes));
         }
 
-        summary.setText(summaryText);
-        summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE);
+        bindIconAndTitle(convertView);
+        bindSummary(convertView, summaryText);
+    }
+
+    protected final void bindAction(View view, int visibility, int iconId, String description) {
+        final ImageView actionIcon = (ImageView) view.findViewById(R.id.action_icon);
+        final View verticalDivider = view.findViewById(R.id.vertical_divider);
+        final View actionIconArea = view.findViewById(R.id.action_icon_area);
+
+        verticalDivider.setVisibility(visibility);
+        actionIconArea.setVisibility(visibility);
+        actionIconArea.setOnClickListener(visibility == View.VISIBLE ? this::onActionClick : null);
+        if (description != null) {
+            actionIconArea.setContentDescription(description);
+        }
+        if (iconId > 0) {
+            actionIcon.setImageDrawable(IconUtils.applyTintColor(view.getContext(), iconId,
+                    R.color.item_action_icon));
+        }
+    }
+
+    protected void onActionClick(View view) {
+        RootsFragment.ejectClicked(view, root, mActionHandler);
+    }
+
+    protected final void bindIconAndTitle(View view) {
+        bindIcon(view, root.loadDrawerIcon(view.getContext()));
+        bindTitle(view);
+    }
+
+    protected void bindSummary(View view, String summary) {
+        final TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
+        summaryView.setText(summary);
+        summaryView.setVisibility(TextUtils.isEmpty(summary) ? View.GONE : View.VISIBLE);
+    }
+
+    private void bindIcon(View view, Drawable drawable) {
+        final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
+        icon.setImageDrawable(drawable);
+    }
+
+    private void bindTitle(View view) {
+        final TextView titleView = (TextView) view.findViewById(android.R.id.title);
+        titleView.setText(title);
     }
 
     @Override
@@ -106,6 +140,11 @@
     }
 
     @Override
+    String getPackageName() {
+        return mPackageName;
+    }
+
+    @Override
     boolean isDropTarget() {
         return root.supportsCreate();
     }
diff --git a/src/com/android/documentsui/sidebar/RootsAdapter.java b/src/com/android/documentsui/sidebar/RootsAdapter.java
index 916d040..a08637c 100644
--- a/src/com/android/documentsui/sidebar/RootsAdapter.java
+++ b/src/com/android/documentsui/sidebar/RootsAdapter.java
@@ -34,6 +34,11 @@
  * {@link Item}s and provides sub-views to {@link android.widget.ListView}.
  */
 class RootsAdapter extends ArrayAdapter<Item> {
+    private static final int TYPE_ROOT = 0;
+    private static final int TYPE_APP = 1;
+    private static final int TYPE_ROOT_AND_APP = 2;
+    private static final int TYPE_SPACER = 3;
+
     private static final Map<String, Long> sIdMap = new HashMap<>();
     // the next available id to associate with a new string id
     private static long sNextAvailableId;
@@ -95,21 +100,25 @@
 
     @Override
     public boolean isEnabled(int position) {
-        return getItemViewType(position) != 1;
+        return getItemViewType(position) != TYPE_SPACER;
     }
 
     @Override
     public int getItemViewType(int position) {
         final Item item = getItem(position);
-        if (item instanceof RootItem || item instanceof AppItem) {
-            return 0;
+        if (item instanceof RootAndAppItem) {
+            return TYPE_ROOT_AND_APP;
+        } else if (item instanceof RootItem) {
+            return TYPE_ROOT;
+        } else if (item instanceof AppItem) {
+            return TYPE_APP;
         } else {
-            return 1;
+            return TYPE_SPACER;
         }
     }
 
     @Override
     public int getViewTypeCount() {
-        return 2;
+        return 4;
     }
 }
diff --git a/src/com/android/documentsui/sidebar/RootsFragment.java b/src/com/android/documentsui/sidebar/RootsFragment.java
index db8d0e8..4d40bbc 100644
--- a/src/com/android/documentsui/sidebar/RootsFragment.java
+++ b/src/com/android/documentsui/sidebar/RootsFragment.java
@@ -16,20 +16,16 @@
 
 package com.android.documentsui.sidebar;
 
+import static com.android.documentsui.base.Shared.compareToIgnoreCaseNullable;
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 import static com.android.documentsui.base.SharedMinimal.VERBOSE;
 
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.app.LoaderManager.LoaderCallbacks;
 import android.content.Context;
 import android.content.Intent;
-import android.content.Loader;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.text.TextUtils;
@@ -49,9 +45,19 @@
 import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.ListView;
 
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.loader.app.LoaderManager;
+import androidx.loader.app.LoaderManager.LoaderCallbacks;
+import androidx.loader.content.Loader;
+
 import com.android.documentsui.ActionHandler;
 import com.android.documentsui.BaseActivity;
 import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.DragHoverListener;
 import com.android.documentsui.Injector;
 import com.android.documentsui.Injector.Injected;
 import com.android.documentsui.ItemDragListener;
@@ -63,6 +69,7 @@
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
+import com.android.documentsui.roots.ProvidersAccess;
 import com.android.documentsui.roots.ProvidersCache;
 import com.android.documentsui.roots.RootsLoader;
 
@@ -70,7 +77,9 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -80,6 +89,8 @@
 
     private static final String TAG = "RootsFragment";
     private static final String EXTRA_INCLUDE_APPS = "includeApps";
+    private static final String PROFILE_TARGET_ACTIVITY =
+            "com.android.internal.app.IntentForwarderActivity";
     private static final int CONTEXT_MENU_ITEM_TIMEOUT = 500;
 
     private final OnItemClickListener mItemListener = new OnItemClickListener() {
@@ -111,6 +122,8 @@
     @Injected
     private ActionHandler mActionHandler;
 
+    private List<Item> mApplicationItemList;
+
     public static RootsFragment show(FragmentManager fm, Intent includeApps) {
         final Bundle args = new Bundle();
         args.putParcelable(EXTRA_INCLUDE_APPS, includeApps);
@@ -161,6 +174,7 @@
             }
         });
         mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        mList.setSelector(new ColorDrawable(Color.TRANSPARENT));
         return view;
     }
 
@@ -197,7 +211,7 @@
                     DocumentsApplication.getDragAndDropManager(activity),
                     this::getItem,
                     mActionHandler);
-            mDragListener = new ItemDragListener<DragHost>(host) {
+            final ItemDragListener<DragHost> listener = new ItemDragListener<DragHost>(host) {
                 @Override
                 public boolean handleDropEventChecked(View v, DragEvent event) {
                     final Item item = getItem(v);
@@ -207,6 +221,8 @@
                     return item.dropOn(event);
                 }
             };
+            mDragListener = DragHoverListener.create(listener, mList);
+            mList.setOnDragListener(mDragListener);
         }
 
         mCallbacks = new LoaderCallbacks<Collection<RootInfo>>() {
@@ -228,12 +244,14 @@
                 final boolean excludeSelf =
                         intent.getBooleanExtra(DocumentsContract.EXTRA_EXCLUDE_SELF, false);
                 final String excludePackage = excludeSelf ? activity.getCallingPackage() : null;
-                List<Item> sortedItems =
-                        sortLoadResult(roots, excludePackage, handlerAppIntent);
+                List<Item> sortedItems = sortLoadResult(roots, excludePackage, handlerAppIntent,
+                        DocumentsApplication.getProvidersCache(getContext()));
                 mAdapter = new RootsAdapter(activity, sortedItems, mDragListener);
                 mList.setAdapter(mAdapter);
 
                 mInjector.shortcutsUpdater.accept(roots);
+                mInjector.appsRowManager.updateList(mApplicationItemList);
+                mInjector.appsRowManager.updateView(activity);
                 onCurrentRootChanged();
             }
 
@@ -246,81 +264,150 @@
     }
 
     /**
+     * If the package name of other providers or apps capable of handling the original intent
+     * include the preferred root source, it will have higher order than others.
      * @param excludePackage Exclude activities from this given package
      * @param handlerAppIntent When not null, apps capable of handling the original intent will
      *            be included in list of roots (in special section at bottom).
      */
-    private List<Item> sortLoadResult(
+    @VisibleForTesting
+    List<Item> sortLoadResult(
             Collection<RootInfo> roots,
             @Nullable String excludePackage,
-            @Nullable Intent handlerAppIntent) {
+            @Nullable Intent handlerAppIntent,
+            ProvidersAccess providersAccess) {
         final List<Item> result = new ArrayList<>();
 
         final List<RootItem> libraries = new ArrayList<>();
-        final List<RootItem> others = new ArrayList<>();
+        final List<RootItem> storageProviders = new ArrayList<>();
+        final List<RootItem> otherProviders = new ArrayList<>();
 
         for (final RootInfo root : roots) {
-            final RootItem item = new RootItem(root, mActionHandler);
+            final RootItem item;
 
-            Activity activity = getActivity();
-            if (root.isHome() && !Shared.shouldShowDocumentsRoot(activity)) {
+            if (root.isExternalStorageHome() && !Shared.shouldShowDocumentsRoot(getContext())) {
                 continue;
-            } else if (root.isLibrary()) {
+            } else if (root.isLibrary() || root.isDownloads()) {
+                item = new RootItem(root, mActionHandler);
                 libraries.add(item);
+            } else if (root.isStorage()) {
+                item = new RootItem(root, mActionHandler);
+                storageProviders.add(item);
             } else {
-                others.add(item);
+                item = new RootItem(root, mActionHandler,
+                        providersAccess.getPackageName(root.authority));
+                otherProviders.add(item);
             }
         }
 
         final RootComparator comp = new RootComparator();
         Collections.sort(libraries, comp);
-        Collections.sort(others, comp);
+        Collections.sort(storageProviders, comp);
 
         if (VERBOSE) Log.v(TAG, "Adding library roots: " + libraries);
         result.addAll(libraries);
+
         // Only add the spacer if it is actually separating something.
-        if (!libraries.isEmpty() && !others.isEmpty()) {
+        if (!result.isEmpty() && !storageProviders.isEmpty()) {
             result.add(new SpacerItem());
         }
-
-        if (VERBOSE) Log.v(TAG, "Adding plain roots: " + libraries);
-        result.addAll(others);
+        if (VERBOSE) Log.v(TAG, "Adding storage roots: " + storageProviders);
+        result.addAll(storageProviders);
 
         // Include apps that can handle this intent too.
         if (handlerAppIntent != null) {
-            includeHandlerApps(handlerAppIntent, excludePackage, result);
+            includeHandlerApps(handlerAppIntent, excludePackage, result, otherProviders);
+        } else {
+            // Only add providers
+            Collections.sort(otherProviders, comp);
+            if (!result.isEmpty() && !otherProviders.isEmpty()) {
+                result.add(new SpacerItem());
+            }
+            if (VERBOSE) Log.v(TAG, "Adding plain roots: " + otherProviders);
+            result.addAll(otherProviders);
+
+            mApplicationItemList = new ArrayList<>();
+            for (Item item : otherProviders) {
+                mApplicationItemList.add(item);
+            }
         }
 
         return result;
     }
 
     /**
-     * Adds apps capable of handling the original intent will be included in list of roots (in
-     * special section at bottom).
+     * Adds apps capable of handling the original intent will be included in list of roots. If
+     * the providers and apps are the same package name, combine them as RootAndAppItems.
      */
     private void includeHandlerApps(
-            Intent handlerAppIntent, @Nullable String excludePackage, List<Item> result) {
+            Intent handlerAppIntent, @Nullable String excludePackage, List<Item> result,
+            List<RootItem> otherProviders) {
         if (VERBOSE) Log.v(TAG, "Adding handler apps for intent: " + handlerAppIntent);
         Context context = getContext();
         final PackageManager pm = context.getPackageManager();
         final List<ResolveInfo> infos = pm.queryIntentActivities(
                 handlerAppIntent, PackageManager.MATCH_DEFAULT_ONLY);
 
-        final List<AppItem> apps = new ArrayList<>();
+        final List<Item> rootList = new ArrayList<>();
+        final Map<String, ResolveInfo> appsMapping = new HashMap<>();
+        final Map<String, Item> appItems = new HashMap<>();
+        ProfileItem profileItem = null;
 
         // Omit ourselves and maybe calling package from the list
         for (ResolveInfo info : infos) {
-            if (!context.getPackageName().equals(info.activityInfo.packageName) &&
-                    !TextUtils.equals(excludePackage, info.activityInfo.packageName)) {
-                final AppItem app = new AppItem(info, mActionHandler);
-                if (VERBOSE) Log.v(TAG, "Adding handler app: " + app);
-                apps.add(app);
+            final String packageName = info.activityInfo.packageName;
+            if (!context.getPackageName().equals(packageName) &&
+                    !TextUtils.equals(excludePackage, packageName)) {
+                appsMapping.put(packageName, info);
+
+                // for change personal profile root.
+                if (PROFILE_TARGET_ACTIVITY.equals(info.activityInfo.targetActivity)) {
+                    profileItem = new ProfileItem(info, info.loadLabel(pm).toString(),
+                            mActionHandler);
+                } else {
+                    final Item item = new AppItem(info, info.loadLabel(pm).toString(),
+                            mActionHandler);
+                    appItems.put(packageName, item);
+                    if (VERBOSE) Log.v(TAG, "Adding handler app: " + item);
+                }
             }
         }
 
-        if (apps.size() > 0) {
+        // If there are some providers and apps has the same package name, combine them as one item.
+        for (RootItem rootItem : otherProviders) {
+            final String packageName = rootItem.getPackageName();
+            final ResolveInfo resolveInfo = appsMapping.get(packageName);
+
+            final Item item;
+            if (resolveInfo != null) {
+                item = new RootAndAppItem(rootItem.root, resolveInfo, mActionHandler);
+                appItems.remove(packageName);
+            } else {
+                item = rootItem;
+            }
+
+            if (VERBOSE) Log.v(TAG, "Adding provider : " + item);
+            rootList.add(item);
+        }
+
+        rootList.addAll(appItems.values());
+
+        if (!result.isEmpty() && !rootList.isEmpty()) {
             result.add(new SpacerItem());
-            result.addAll(apps);
+        }
+
+        final String preferredRootPackage = getResources().getString(
+                R.string.preferred_root_package, "");
+
+        final ItemComparator comp = new ItemComparator(preferredRootPackage);
+        Collections.sort(rootList, comp);
+        result.addAll(rootList);
+
+        mApplicationItemList = rootList;
+
+        if (profileItem != null) {
+            result.add(new SpacerItem());
+            result.add(profileItem);
         }
     }
 
@@ -341,7 +428,7 @@
             mList.setLongClickable(false);
         }
 
-        getLoaderManager().restartLoader(2, null, mCallbacks);
+        LoaderManager.getInstance(this).restartLoader(2, null, mCallbacks);
     }
 
     public void onCurrentRootChanged() {
@@ -355,6 +442,8 @@
             if (item instanceof RootItem) {
                 final RootInfo testRoot = ((RootItem) item).root;
                 if (Objects.equals(testRoot, root)) {
+                    // b/37358441 should reload all root title after configuration changed
+                    root.title = testRoot.title;
                     mList.setItemChecked(i, true);
                     return;
                 }
@@ -397,7 +486,7 @@
         final RootItem rootItem = (RootItem) mAdapter.getItem(adapterMenuInfo.position);
         switch (item.getItemId()) {
             case R.id.root_menu_eject_root:
-                final View ejectIcon = adapterMenuInfo.targetView.findViewById(R.id.eject_icon);
+                final View ejectIcon = adapterMenuInfo.targetView.findViewById(R.id.action_icon);
                 ejectClicked(ejectIcon, rootItem.root, mActionHandler);
                 return true;
             case R.id.root_menu_open_in_new_window:
@@ -410,7 +499,9 @@
                 mActionHandler.openSettings(rootItem.root);
                 return true;
             default:
-                if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
+                if (DEBUG) {
+                    Log.d(TAG, "Unhandled menu item selected: " + item);
+                }
                 return false;
         }
     }
@@ -460,6 +551,53 @@
         }
     }
 
+    /**
+     * The comparator of {@link AppItem}, {@link RootItem} and {@link RootAndAppItem}.
+     * Sort by if the item's package name starts with the preferred package name,
+     * then title, then summary. Because the {@link AppItem} doesn't have summary,
+     * it will have lower order than other same title items.
+     */
+    @VisibleForTesting
+    static class ItemComparator implements Comparator<Item> {
+        private final String mPreferredPackageName;
+
+        ItemComparator(String preferredPackageName) {
+            mPreferredPackageName = preferredPackageName;
+        }
+
+        @Override
+        public int compare(Item lhs, Item rhs) {
+            // Sort by whether the item starts with preferred package name
+            if (!mPreferredPackageName.isEmpty()) {
+                if (lhs.getPackageName().startsWith(mPreferredPackageName)) {
+                    if (!rhs.getPackageName().startsWith(mPreferredPackageName)) {
+                        // lhs starts with it, but rhs doesn't start with it
+                        return -1;
+                    }
+                } else {
+                    if (rhs.getPackageName().startsWith(mPreferredPackageName)) {
+                        // lhs doesn't start with it, but rhs starts with it
+                        return 1;
+                    }
+                }
+            }
+
+            // Sort by title
+            int score = compareToIgnoreCaseNullable(lhs.title, rhs.title);
+            if (score != 0) {
+                return score;
+            }
+
+            // Sort by summary. If the item is AppItem, it doesn't have summary.
+            // So, the RootItem or RootAndAppItem will have higher order than AppItem.
+            if (lhs instanceof RootItem) {
+                return rhs instanceof RootItem ? compareToIgnoreCaseNullable(
+                        ((RootItem) lhs).root.summary, ((RootItem) rhs).root.summary) : 1;
+            }
+            return rhs instanceof RootItem ? -1 : 0;
+        }
+    }
+
     @FunctionalInterface
     interface RootUpdater {
         void updateDocInfoForRoot(DocumentInfo doc);
diff --git a/src/com/android/documentsui/sidebar/SpacerItem.java b/src/com/android/documentsui/sidebar/SpacerItem.java
index 89cea1a..4ca466e 100644
--- a/src/com/android/documentsui/sidebar/SpacerItem.java
+++ b/src/com/android/documentsui/sidebar/SpacerItem.java
@@ -33,7 +33,7 @@
 
     public SpacerItem() {
         // Multiple spacer items can share the same string id as they're identical.
-        super(R.layout.item_root_spacer, STRING_ID);
+        super(R.layout.item_root_spacer, "" /* title */, STRING_ID);
     }
 
     @Override
@@ -48,6 +48,8 @@
 
     @Override
     void open() {
-        if (DEBUG) Log.d(TAG, "Ignoring click/hover on spacer item.");
+        if (DEBUG) {
+            Log.d(TAG, "Ignoring click/hover on spacer item.");
+        }
     }
 }
diff --git a/src/com/android/documentsui/sorting/DropdownSortWidgetController.java b/src/com/android/documentsui/sorting/DropdownSortWidgetController.java
deleted file mode 100644
index 489e184..0000000
--- a/src/com/android/documentsui/sorting/DropdownSortWidgetController.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.sorting;
-
-import android.annotation.StringRes;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.PopupMenu;
-import android.widget.TextView;
-
-import com.android.documentsui.R;
-import com.android.documentsui.sorting.SortController.WidgetController;
-import com.android.documentsui.sorting.SortDimension.SortDirection;
-import com.android.documentsui.sorting.SortModel.SortDimensionId;
-import com.android.documentsui.sorting.SortModel.UpdateType;
-
-/**
- * View controller for the sort widget in grid mode and in small screens.
- */
-public final class DropdownSortWidgetController implements WidgetController {
-
-    private static final int LEVEL_UPWARD = 0;
-    private static final int LEVEL_DOWNWARD = 10000;
-
-    private final SortModel mModel;
-    private final View mWidget;
-    private final TextView mDimensionButton;
-    private final PopupMenu mMenu;
-    private final ImageView mArrow;
-    private final SortModel.UpdateListener mListener;
-
-    public DropdownSortWidgetController(SortModel model, View widget) {
-        mModel = model;
-        mWidget = widget;
-
-        mDimensionButton = (TextView) mWidget.findViewById(R.id.sort_dimen_dropdown);
-        mDimensionButton.setOnClickListener(this::showMenu);
-
-        mMenu = new PopupMenu(widget.getContext(), mDimensionButton, Gravity.END | Gravity.TOP);
-        mMenu.setOnMenuItemClickListener(this::onSelectDimension);
-
-        mArrow = (ImageView) mWidget.findViewById(R.id.sort_arrow);
-        mArrow.setOnClickListener(this::onChangeDirection);
-
-        populateMenuItems();
-        onModelUpdate(mModel, SortModel.UPDATE_TYPE_UNSPECIFIED);
-
-        mListener = this::onModelUpdate;
-        mModel.addListener(mListener);
-    }
-
-    @Override
-    public void setVisibility(int visibility) {
-        mWidget.setVisibility(visibility);
-    }
-
-    @Override
-    public void destroy() {
-        mModel.removeListener(mListener);
-    }
-
-    private void populateMenuItems() {
-        Menu menu = mMenu.getMenu();
-        menu.clear();
-        for (int i = 0; i < mModel.getSize(); ++i) {
-            SortDimension dimension = mModel.getDimensionAt(i);
-            if (dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
-                menu.add(0, dimension.getId(), Menu.NONE, dimension.getLabelId());
-            }
-        }
-    }
-
-    private void showMenu(View v) {
-        mMenu.show();
-    }
-
-    private void onModelUpdate(SortModel model, @UpdateType int updateType) {
-        final @SortDimensionId int sortedId = model.getSortedDimensionId();
-
-        if ((updateType & SortModel.UPDATE_TYPE_VISIBILITY) != 0) {
-            updateVisibility();
-        }
-
-        if ((updateType & SortModel.UPDATE_TYPE_SORTING) != 0) {
-            bindSortedDimension(sortedId);
-            bindSortDirection(sortedId);
-        }
-    }
-
-    private void updateVisibility() {
-        Menu menu = mMenu.getMenu();
-
-        for (int i = 0; i < menu.size(); ++i) {
-            MenuItem item = menu.getItem(i);
-            SortDimension dimension = mModel.getDimensionById(item.getItemId());
-            item.setVisible(dimension.getVisibility() == View.VISIBLE);
-        }
-    }
-
-    private void bindSortedDimension(@SortDimensionId int sortedId) {
-        if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
-            mDimensionButton.setText(R.string.not_sorted);
-        } else {
-            SortDimension dimension = mModel.getDimensionById(sortedId);
-            mDimensionButton.setText(dimension.getLabelId());
-        }
-    }
-
-    private void bindSortDirection(@SortDimensionId int sortedId) {
-        if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
-            mArrow.setVisibility(View.INVISIBLE);
-        } else {
-            final SortDimension dimension = mModel.getDimensionById(sortedId);
-            switch (dimension.getSortDirection()) {
-                case SortDimension.SORT_DIRECTION_NONE:
-                    mArrow.setVisibility(View.INVISIBLE);
-                    break;
-                case SortDimension.SORT_DIRECTION_ASCENDING:
-                    showArrow(LEVEL_UPWARD, R.string.sort_direction_ascending);
-                    break;
-                case SortDimension.SORT_DIRECTION_DESCENDING:
-                    showArrow(LEVEL_DOWNWARD, R.string.sort_direction_descending);
-                    break;
-                default:
-                    throw new IllegalStateException(
-                            "Unknown sort direction: " + dimension.getSortDirection() + ".");
-            }
-        }
-    }
-
-    private void showArrow(int level, @StringRes int descriptionId) {
-        mArrow.setVisibility(View.VISIBLE);
-
-        mArrow.getDrawable().mutate();
-        mArrow.setImageLevel(level);
-        mArrow.setContentDescription(mArrow.getContext().getString(descriptionId));
-    }
-
-    private boolean onSelectDimension(MenuItem item) {
-        final @SortDirection int preferredDirection = mModel.getCurrentSortDirection();
-
-        final SortDimension dimension = mModel.getDimensionById(item.getItemId());
-        final @SortDirection int direction;
-        if ((dimension.getSortCapability() & preferredDirection) > 0) {
-            direction = preferredDirection;
-        } else {
-            direction = dimension.getDefaultSortDirection();
-        }
-
-        mModel.sortByUser(dimension.getId(), direction);
-
-        return true;
-    }
-
-    private void onChangeDirection(View v) {
-        final @SortDimensionId int id = mModel.getSortedDimensionId();
-        assert(id != SortModel.SORT_DIMENSION_ID_UNKNOWN);
-
-        final SortDimension dimension = mModel.getDimensionById(id);
-        mModel.sortByUser(dimension.getId(), dimension.getNextDirection());
-    }
-}
diff --git a/src/com/android/documentsui/sorting/HeaderCell.java b/src/com/android/documentsui/sorting/HeaderCell.java
index fa0f5c7..43e254e 100644
--- a/src/com/android/documentsui/sorting/HeaderCell.java
+++ b/src/com/android/documentsui/sorting/HeaderCell.java
@@ -19,8 +19,8 @@
 import android.animation.AnimatorInflater;
 import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
-import android.annotation.AnimatorRes;
-import android.annotation.StringRes;
+import androidx.annotation.AnimatorRes;
+import androidx.annotation.StringRes;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.Gravity;
diff --git a/src/com/android/documentsui/sorting/SortController.java b/src/com/android/documentsui/sorting/SortController.java
index 1425e50..ccfc3f1 100644
--- a/src/com/android/documentsui/sorting/SortController.java
+++ b/src/com/android/documentsui/sorting/SortController.java
@@ -16,10 +16,14 @@
 
 package com.android.documentsui.sorting;
 
-import android.annotation.Nullable;
-import android.app.Activity;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
 import android.view.View;
 
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.Injector;
+import com.android.documentsui.MetricConsts;
 import com.android.documentsui.Metrics;
 import com.android.documentsui.R;
 import com.android.documentsui.base.State;
@@ -32,72 +36,60 @@
  */
 public final class SortController {
 
-    private final WidgetController mDropdownController;
     private final @Nullable WidgetController mTableHeaderController;
 
-    public SortController(
-            WidgetController dropdownController,
-            @Nullable WidgetController tableHeaderController) {
+    public SortController(@Nullable WidgetController tableHeaderController) {
 
-        assert(dropdownController != null);
-        mDropdownController = dropdownController;
         mTableHeaderController = tableHeaderController;
     }
 
     public void onViewModeChanged(@ViewMode int mode) {
         // in phone layouts we only ever have the dropdown sort controller.
         if (mTableHeaderController == null) {
-            mDropdownController.setVisibility(View.VISIBLE);
             return;
         }
 
         // in tablet mode, we have fancy pants tabular header.
-        switch (mode) {
-            case State.MODE_GRID:
-            case State.MODE_UNKNOWN:
-                mTableHeaderController.setVisibility(View.GONE);
-                mDropdownController.setVisibility(View.VISIBLE);
-                break;
-            case State.MODE_LIST:
-                mTableHeaderController.setVisibility(View.VISIBLE);
-                mDropdownController.setVisibility(View.GONE);
-                break;
-        }
+        mTableHeaderController.setVisibility(mode == State.MODE_LIST ? View.VISIBLE : View.GONE);
     }
 
     public void destroy() {
-        mDropdownController.destroy();
         if (mTableHeaderController != null) {
             mTableHeaderController.destroy();
         }
     }
 
     public static SortController create(
-            Activity activity,
+            FragmentActivity activity,
             @ViewMode int initialMode,
             SortModel sortModel) {
 
+        final Injector<?> injector = ((BaseActivity)activity).getInjector();
         sortModel.setMetricRecorder((SortDimension dimension) -> {
+            int sortType = MetricConsts.USER_ACTION_UNKNOWN;
             switch (dimension.getId()) {
                 case SortModel.SORT_DIMENSION_ID_TITLE:
-                    Metrics.logUserAction(activity, Metrics.USER_ACTION_SORT_NAME);
+                    sortType = MetricConsts.USER_ACTION_SORT_NAME;
                     break;
                 case SortModel.SORT_DIMENSION_ID_SIZE:
-                    Metrics.logUserAction(activity, Metrics.USER_ACTION_SORT_SIZE);
+                    sortType = MetricConsts.USER_ACTION_SORT_SIZE;
                     break;
                 case SortModel.SORT_DIMENSION_ID_DATE:
-                    Metrics.logUserAction(activity, Metrics.USER_ACTION_SORT_DATE);
+                    sortType = MetricConsts.USER_ACTION_SORT_DATE;
                     break;
+                case SortModel.SORT_DIMENSION_ID_FILE_TYPE:
+                    sortType = MetricConsts.USER_ACTION_SORT_TYPE;
+                    break;
+            }
+
+            Metrics.logUserAction(sortType);
+            if (injector.pickResult != null) {
+                injector.pickResult.increaseActionCount();
             }
         });
 
         SortController controller = new SortController(
-                new DropdownSortWidgetController(
-                        sortModel,
-                        activity.findViewById(R.id.dropdown_sort_widget)),
-                TableHeaderController.create(
-                        sortModel,
-                        activity.findViewById(R.id.table_header)));
+                TableHeaderController.create(sortModel, activity.findViewById(R.id.table_header)));
 
         controller.onViewModeChanged(initialMode);
         return controller;
diff --git a/src/com/android/documentsui/sorting/SortDimension.java b/src/com/android/documentsui/sorting/SortDimension.java
index 6411b98..33333b2 100644
--- a/src/com/android/documentsui/sorting/SortDimension.java
+++ b/src/com/android/documentsui/sorting/SortDimension.java
@@ -16,12 +16,13 @@
 
 package com.android.documentsui.sorting;
 
-import android.annotation.IntDef;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.annotation.StringRes;
 import android.view.View;
 
+import androidx.annotation.IntDef;
+import androidx.annotation.StringRes;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -179,7 +180,7 @@
         out.writeInt(mVisibility);
     }
 
-    public static Parcelable.Creator<SortDimension> CREATOR =
+    public static final Parcelable.Creator<SortDimension> CREATOR =
             new Parcelable.Creator<SortDimension>() {
 
         @Override
diff --git a/src/com/android/documentsui/sorting/SortListFragment.java b/src/com/android/documentsui/sorting/SortListFragment.java
new file mode 100644
index 0000000..83db08a
--- /dev/null
+++ b/src/com/android/documentsui/sorting/SortListFragment.java
@@ -0,0 +1,179 @@
+package com.android.documentsui.sorting;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckedTextView;
+import android.widget.FrameLayout;
+import android.widget.ListView;
+
+import androidx.annotation.StringRes;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.documentsui.R;
+import com.android.documentsui.sorting.SortDimension.SortDirection;
+import com.android.documentsui.sorting.SortModel.SortDimensionId;
+
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetDialog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SortListFragment extends DialogFragment {
+
+    private static final String TAG_MODEL = "sorting_model";
+    private static final String TAG_SORTING_LIST = "sorting_list";
+
+    private SortModel mModel;
+    private List<SortItem> mSortingList;
+
+    public static void show(FragmentManager fm, SortModel model) {
+        SortListFragment fragment = new SortListFragment();
+        Bundle args = new Bundle();
+        args.putParcelable(TAG_MODEL, model);
+        fragment.setArguments(args);
+        fragment.show(fm, TAG_SORTING_LIST);
+    }
+
+    public SortListFragment() {
+        super();
+    }
+
+    private void onItemClicked (AdapterView<?> parent, View view, int position, long id) {
+        SortItem item = mSortingList.get(position);
+        mModel.sortByUser(item.id, item.direction);
+        getDialog().dismiss();
+    }
+
+    private void setupSortingList() {
+        mSortingList = new ArrayList<>();
+        for (int i = 0; i < mModel.getSize(); ++i) {
+            SortDimension dimension = mModel.getDimensionAt(i);
+            if (dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
+                switch (dimension.getId()) {
+                    case SortModel.SORT_DIMENSION_ID_TITLE:
+                    case SortModel.SORT_DIMENSION_ID_FILE_TYPE:
+                        addBothDirectionDimension(dimension, true);
+                        break;
+                    case SortModel.SORT_DIMENSION_ID_DATE:
+                    case SortModel.SORT_DIMENSION_ID_SIZE:
+                        addBothDirectionDimension(dimension, false);
+                        break;
+                    default:
+                        mSortingList.add(new SortItem(dimension));
+                        break;
+                }
+            }
+        }
+    }
+
+    private void addBothDirectionDimension(SortDimension source, boolean ascendingFirst) {
+        SortItem ascending = new SortItem(source.getId(),
+                SortDimension.SORT_DIRECTION_ASCENDING,
+                getSheetLabelId(source, SortDimension.SORT_DIRECTION_ASCENDING));
+        SortItem descending = new SortItem(source.getId(),
+                SortDimension.SORT_DIRECTION_DESCENDING,
+                getSheetLabelId(source, SortDimension.SORT_DIRECTION_DESCENDING));
+        mSortingList.add(ascendingFirst ? ascending : descending);
+        mSortingList.add(ascendingFirst ? descending : ascending);
+    }
+
+    public static @StringRes int getSheetLabelId(SortDimension dimension, @SortDirection int direction) {
+        boolean isAscending = direction == SortDimension.SORT_DIRECTION_ASCENDING;
+        switch (dimension.getId()) {
+            case SortModel.SORT_DIMENSION_ID_TITLE:
+                return isAscending ? R.string.sort_dimension_name_ascending :
+                        R.string.sort_dimension_name_descending;
+            case SortModel.SORT_DIMENSION_ID_DATE:
+                return isAscending ? R.string.sort_dimension_date_ascending :
+                        R.string.sort_dimension_date_descending;
+            case SortModel.SORT_DIMENSION_ID_FILE_TYPE:
+                return isAscending ? R.string.sort_dimension_file_type_ascending :
+                        R.string.sort_dimension_file_type_descending;
+            case SortModel.SORT_DIMENSION_ID_SIZE:
+                return isAscending ? R.string.sort_dimension_size_ascending :
+                        R.string.sort_dimension_size_descending;
+            default:
+                return dimension.getLabelId();
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        if (savedInstanceState == null) {
+            Bundle args = getArguments();
+            mModel = args.getParcelable(TAG_MODEL);
+        } else {
+            mModel = savedInstanceState.getParcelable(TAG_MODEL);
+        }
+        setupSortingList();
+
+        BottomSheetDialog dialog =
+                new BottomSheetDialog(getContext());
+        dialog.setContentView(R.layout.dialog_sorting);
+
+        // Workaround for solve issue about dialog not full expanded when landscape.
+        FrameLayout bottomSheet = (FrameLayout)
+                dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
+        BottomSheetBehavior.from(bottomSheet)
+                .setState(BottomSheetBehavior.STATE_EXPANDED);
+
+        ListView listView = dialog.findViewById(R.id.sorting_dialog_list);
+
+        listView.setAdapter(new SortingListAdapter(getContext(), mSortingList));
+        listView.setOnItemClickListener(this::onItemClicked);
+
+        return dialog;
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putParcelable(TAG_MODEL, mModel);
+    }
+
+    private class SortingListAdapter extends ArrayAdapter<SortItem> {
+
+        public SortingListAdapter(Context context, List<SortItem> list) {
+            super(context, R.layout.sort_list_item, list);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View view = super.getView(position, convertView, parent);
+            final SortItem item = getItem(position);
+            final CheckedTextView text = view.findViewById(android.R.id.text1);
+            text.setText(getString(item.labelId));
+
+            boolean selected = item.id == mModel.getSortedDimensionId()
+                    && item.direction == mModel.getCurrentSortDirection();
+            text.setChecked(selected);
+            return view;
+        }
+    }
+
+    private static class SortItem {
+
+        @SortDimensionId final int id;
+        @SortDirection final int direction;
+        @StringRes final int labelId;
+
+        SortItem(SortDimension dimension) {
+            id = dimension.getId();
+            direction = dimension.getDefaultSortDirection();
+            labelId = dimension.getLabelId();
+        }
+
+        SortItem(@SortDimensionId int id, @SortDirection int direction, @StringRes int labelId) {
+            this.id = id;
+            this.direction = direction;
+            this.labelId = labelId;
+        }
+    }
+}
diff --git a/src/com/android/documentsui/sorting/SortModel.java b/src/com/android/documentsui/sorting/SortModel.java
index 311e89f..4e544a9 100644
--- a/src/com/android/documentsui/sorting/SortModel.java
+++ b/src/com/android/documentsui/sorting/SortModel.java
@@ -18,19 +18,20 @@
 
 import static com.android.documentsui.base.SharedMinimal.DEBUG;
 
-import android.annotation.IntDef;
-import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
 
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
 import com.android.documentsui.R;
 import com.android.documentsui.base.Lookup;
 import com.android.documentsui.sorting.SortDimension.SortDirection;
@@ -356,7 +357,9 @@
         if (!mIsUserSpecified) {
             SortDimension dimension = mDimensions.get(mDefaultDimensionId);
             if (dimension == null) {
-                if (DEBUG) Log.d(TAG, "No default sort dimension.");
+                if (DEBUG) {
+                    Log.d(TAG, "No default sort dimension.");
+                }
                 return;
             }
 
@@ -418,7 +421,8 @@
         out.writeInt(getSortedDimensionId());
     }
 
-    public static Parcelable.Creator<SortModel> CREATOR = new Parcelable.Creator<SortModel>() {
+    public static final Parcelable.Creator<SortModel> CREATOR =
+            new Parcelable.Creator<SortModel>() {
 
         @Override
         public SortModel createFromParcel(Parcel in) {
diff --git a/src/com/android/documentsui/theme/ThemeOverlayManager.java b/src/com/android/documentsui/theme/ThemeOverlayManager.java
new file mode 100644
index 0000000..ca83268
--- /dev/null
+++ b/src/com/android/documentsui/theme/ThemeOverlayManager.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 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.documentsui.theme;
+
+import android.content.Context;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
+import androidx.core.util.Consumer;
+
+import java.util.List;
+
+/**
+ * ThemeOverlayManager manage runtime resource overlay packages of DocumentsUI
+ */
+public class ThemeOverlayManager {
+    private static final String TAG = ThemeOverlayManager.class.getSimpleName();
+    private static final String PERMISSION_CHANGE_OVERLAY_PACKAGES =
+            "android.permission.CHANGE_OVERLAY_PACKAGES";
+
+    private final OverlayManager mOverlayManager;
+    private String mTargetPackageId;
+    private UserHandle mUserHandle;
+
+    public ThemeOverlayManager(@NonNull OverlayManager overlayManager, String targetPackageId) {
+        mOverlayManager = overlayManager;
+        mTargetPackageId = targetPackageId;
+        mUserHandle = UserHandle.of(UserHandle.myUserId());
+    }
+
+    /**
+     * Apply runtime overlay package, dynamic enabled overlay do not support priority yet
+     *
+     * @param context the activity or context from caller
+     * @param enabled whether or not enable overlay package
+     */
+    public void applyOverlays(Context context, boolean enabled, Consumer<Boolean> callback) {
+        if (ContextCompat.checkSelfPermission(context, PERMISSION_CHANGE_OVERLAY_PACKAGES)
+                == PackageManager.PERMISSION_GRANTED) {
+            setEnabled(enabled, callback);
+        } else {
+            Log.w(TAG, "Permission: " + PERMISSION_CHANGE_OVERLAY_PACKAGES + " did not granted!");
+            callback.accept(false);
+        }
+    }
+
+    private List<OverlayInfo> getOverlayInfo() {
+        // (b/132933212): Only static overlay package support priority attrs
+        // TODO: Alternative way to support enabled multiple overlay packages by priority is
+        //       tag meta-data in the application of overlay package's AndroidManifest.xml
+        // TODO: Parse meta data through PM in DocumentsApplication and use collection to reorder
+        return mOverlayManager.getOverlayInfosForTarget(mTargetPackageId, mUserHandle);
+    }
+
+    /**
+     * Return the OverlayInfo which is provided by the docsUI overlay package located product,
+     * system or vendor. We assume there should only one docsUI overlay package because priority
+     * not work for non-static overlay, so vendor should put only one docsUI overlay package.
+     *
+     * @param pm the PackageManager
+     */
+    @Nullable
+    public OverlayInfo getValidOverlay(@NonNull PackageManager pm) {
+        for (OverlayInfo info : getOverlayInfo()) {
+            try {
+                final ApplicationInfo ai = pm.getApplicationInfo(info.getPackageName(), 0);
+                // Since isProduct(), isVendor() and isSystemApp() functions in ApplicationInfo are
+                // hidden. The best way to avoid unknown sideload APKs is filter path by string
+                // comparison.
+                final String sourceDir = ai.sourceDir;
+                if (sourceDir.startsWith(Environment.getProductDirectory().getAbsolutePath())
+                        || sourceDir.startsWith(Environment.getVendorDirectory().getAbsolutePath())
+                        || sourceDir.startsWith(Environment.getRootDirectory().getAbsolutePath())) {
+                    return info;
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "Can't get ApplicationInfo of overlay package " + info.getPackageName());
+            }
+        }
+        return null;
+    }
+
+    private void setEnabled(boolean enabled, Consumer<Boolean> callback) {
+        new AsyncTask<Void, Void, Boolean>() {
+            @Override
+            protected Boolean doInBackground(Void... params) {
+                return setEnabledOverlayPackages(getOverlayInfo(), enabled);
+            }
+
+            @Override
+            protected void onPostExecute(Boolean result) {
+                super.onPostExecute(result);
+                if (callback != null) {
+                    callback.accept(result);
+                }
+            }
+        }.execute();
+    }
+
+    private boolean setEnabledOverlayPackages(List<OverlayInfo> infos, boolean enabled) {
+        boolean bSuccess = true;
+        for (OverlayInfo info : infos) {
+            try {
+                if (info.isEnabled() != enabled) {
+                    mOverlayManager.setEnabled(info.getPackageName(), enabled, mUserHandle);
+                } else {
+                    Log.w(TAG, "Skip enabled overlay package:" + info.getPackageName()
+                            + ", user:" + mUserHandle);
+                    bSuccess = false;
+                }
+            } catch (RuntimeException re) {
+                Log.e(TAG, "Failed to enable overlay: " + info.getPackageName() + ", user: "
+                        + mUserHandle);
+                bSuccess = false;
+            }
+        }
+        return bSuccess;
+    }
+}
diff --git a/src/com/android/documentsui/ui/DialogController.java b/src/com/android/documentsui/ui/DialogController.java
index 0de9868..8e96739 100644
--- a/src/com/android/documentsui/ui/DialogController.java
+++ b/src/com/android/documentsui/ui/DialogController.java
@@ -16,26 +16,28 @@
 package com.android.documentsui.ui;
 
 import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.FragmentManager;
 import android.content.DialogInterface;
-import android.support.design.widget.Snackbar;
 import android.widget.Button;
 import android.widget.TextView;
 
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentManager;
+
 import com.android.documentsui.R;
 import com.android.documentsui.base.ConfirmationCallback;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Features;
-import com.android.documentsui.picker.OverwriteConfirmFragment;
+import com.android.documentsui.picker.ConfirmFragment;
 import com.android.documentsui.services.FileOperation;
-import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.services.FileOperationService;
-import com.android.documentsui.services.FileOperations.Callback.Status;
+import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.services.FileOperations;
+import com.android.documentsui.services.FileOperations.Callback.Status;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.snackbar.Snackbar;
 
 import java.util.List;
-import javax.annotation.Nullable;
 
 public interface DialogController {
 
@@ -55,7 +57,7 @@
     void showDocumentsClipped(int size);
 
     // Dialogs used in PickActivity
-    void confirmOverwrite(FragmentManager fm, DocumentInfo overwriteTarget);
+    void confirmAction(FragmentManager fm, DocumentInfo pickTarget, int type);
 
     // Should be private, but Java doesn't like me treating an interface like a mini-package.
     public static final class RuntimeDialogController implements DialogController {
@@ -85,7 +87,7 @@
             // but as a simple runtime dialog. So rotating a device with an
             // active delete dialog...results in that dialog disappearing.
             // We can do better, but don't have cycles for it now.
-            final AlertDialog alertDialog = new AlertDialog.Builder(mActivity)
+            final AlertDialog alertDialog = new MaterialAlertDialogBuilder(mActivity)
                     .setView(message)
                     .setPositiveButton(
                             android.R.string.ok,
@@ -108,8 +110,7 @@
         }
 
         @Override
-        public void showFileOperationStatus(@Status int status, @OpType int opType,
-                int docCount) {
+        public void showFileOperationStatus(@Status int status, @OpType int opType, int docCount) {
             if (status == FileOperations.Callback.STATUS_REJECTED) {
                 showOperationUnsupported();
                 return;
@@ -199,8 +200,8 @@
         }
 
         @Override
-        public void confirmOverwrite(FragmentManager fm, DocumentInfo overwriteTarget) {
-            OverwriteConfirmFragment.show(fm, overwriteTarget);
+        public void confirmAction(FragmentManager fm, DocumentInfo pickTarget, int type) {
+            ConfirmFragment.show(fm, pickTarget, type);
         }
     }
 
diff --git a/src/com/android/documentsui/ui/DocumentDebugInfo.java b/src/com/android/documentsui/ui/DocumentDebugInfo.java
index 80dc8c9..b7712c6 100644
--- a/src/com/android/documentsui/ui/DocumentDebugInfo.java
+++ b/src/com/android/documentsui/ui/DocumentDebugInfo.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.ui;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.TextView;
diff --git a/src/com/android/documentsui/ui/MessageBuilder.java b/src/com/android/documentsui/ui/MessageBuilder.java
index 4a4af29..179b73d 100644
--- a/src/com/android/documentsui/ui/MessageBuilder.java
+++ b/src/com/android/documentsui/ui/MessageBuilder.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.ui;
 
-import android.annotation.PluralsRes;
+import androidx.annotation.PluralsRes;
 import android.content.Context;
 import android.text.BidiFormatter;
 import android.net.Uri;
diff --git a/src/com/android/documentsui/ui/OperationProgressDialog.java b/src/com/android/documentsui/ui/OperationProgressDialog.java
index 08cc5d2..1c08580 100644
--- a/src/com/android/documentsui/ui/OperationProgressDialog.java
+++ b/src/com/android/documentsui/ui/OperationProgressDialog.java
@@ -18,20 +18,17 @@
 
 import android.app.Activity;
 import android.app.ProgressDialog;
-import android.content.DialogInterface;
 import android.os.Handler;
 import android.os.Message;
 import android.text.format.DateUtils;
 
+import androidx.annotation.StringRes;
+
 import com.android.documentsui.R;
 import com.android.documentsui.services.FileOperation;
-import com.android.documentsui.services.FileOperationService.MessageType;
-import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperations;
-
-import android.support.annotation.StringRes;
-import android.util.Log;
+import com.android.documentsui.util.FormatUtils;
 
 public class OperationProgressDialog {
 
@@ -74,7 +71,7 @@
                         }
                         if (message.arg2 > 0) {
                             mDialog.setMessage(mActivity.getString(R.string.copy_remaining,
-                                    DateUtils.formatDuration(message.arg2)));
+                                    FormatUtils.formatDuration(message.arg2)));
                         }
                         return true;
                     case FileOperationService.MESSAGE_FINISH:
diff --git a/src/com/android/documentsui/ui/SearchBarScrollingViewBehavior.java b/src/com/android/documentsui/ui/SearchBarScrollingViewBehavior.java
new file mode 100644
index 0000000..5b54f4c
--- /dev/null
+++ b/src/com/android/documentsui/ui/SearchBarScrollingViewBehavior.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 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.documentsui.ui;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+
+import com.google.android.material.appbar.AppBarLayout;
+
+/**
+ * This scrolling view behavior will set the background of the {@link AppBarLayout} as
+ * transparent and without the elevation. Also make header overlapped the scrolling child view.
+ */
+public class SearchBarScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {
+    private boolean mInitialized;
+
+    public SearchBarScrollingViewBehavior(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
+        final boolean changed = super.onDependentViewChanged(parent, child, dependency);
+        if (!mInitialized && dependency instanceof AppBarLayout) {
+            mInitialized = true;
+            final AppBarLayout appBarLayout = (AppBarLayout) dependency;
+            setAppBarLayoutTransparent(appBarLayout);
+        }
+        return changed;
+    }
+
+    private void setAppBarLayoutTransparent(AppBarLayout appBarLayout) {
+        appBarLayout.setBackgroundColor(Color.TRANSPARENT);
+        appBarLayout.setTargetElevation(0);
+    }
+
+    @Override
+    protected boolean shouldHeaderOverlapScrollingChild() {
+        return true;
+    }
+}
+
diff --git a/src/com/android/documentsui/ui/Snackbars.java b/src/com/android/documentsui/ui/Snackbars.java
index 933af97..5d6e012 100644
--- a/src/com/android/documentsui/ui/Snackbars.java
+++ b/src/com/android/documentsui/ui/Snackbars.java
@@ -16,17 +16,22 @@
 
 package com.android.documentsui.ui;
 
-import android.annotation.StringRes;
 import android.app.Activity;
-import android.support.design.widget.Snackbar;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.TextView;
 
+import androidx.annotation.StringRes;
+
 import com.android.documentsui.R;
 import com.android.documentsui.base.Shared;
 
+import com.google.android.material.snackbar.Snackbar;
+
+import java.util.function.Consumer;
+
 public final class Snackbars {
+
     private Snackbars() {}
 
     public static final void showDocumentsClipped(Activity activity, int docCount) {
@@ -73,9 +78,8 @@
     }
 
     public static final void showInspectorError(Activity activity) {
-
         //Document Inspector uses a different view from other files app activities.
-        final View view = activity.findViewById(R.id.fragment_container);
+        final View view = activity.findViewById(R.id.inspector_root);
         Snackbar.make(view, R.string.inspector_load_error, Snackbar.LENGTH_INDEFINITE).show();
     }
 
@@ -83,13 +87,21 @@
         Snackbar snackbar = makeSnackbar(activity, text, Snackbar.LENGTH_SHORT);
         View snackbarLayout = snackbar.getView();
         TextView textView = (TextView)snackbarLayout.findViewById(
-                android.support.design.R.id.snackbar_text);
+                com.google.android.material.R.id.snackbar_text);
         textView.setGravity(Gravity.CENTER_HORIZONTAL);
         textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
         textView.setCompoundDrawablesWithIntrinsicBounds(imageRes, 0, 0, 0);
         snackbar.show();
     }
 
+    public static final Snackbar makeSnackbarWithAction(Activity activity, int docCount,
+            CharSequence message, int duration, CharSequence actionText,
+            Consumer<View> action, final Snackbar.Callback callback) {
+        return makeSnackbar(activity, message, duration)
+                .setAction(actionText, action::accept)
+                .addCallback(callback);
+    }
+
     public static final Snackbar makeSnackbar(Activity activity, @StringRes int messageId,
             int duration) {
         return Snackbars.makeSnackbar(
@@ -98,7 +110,7 @@
 
     public static final Snackbar makeSnackbar(
             Activity activity, CharSequence message, int duration) {
-        final View view = activity.findViewById(R.id.coordinator_layout);
+        final View view = activity.findViewById(R.id.container_save);
         return Snackbar.make(view, message, duration);
     }
 }
diff --git a/src/com/android/documentsui/ui/Views.java b/src/com/android/documentsui/ui/Views.java
new file mode 100644
index 0000000..2ac27b2
--- /dev/null
+++ b/src/com/android/documentsui/ui/Views.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.documentsui.ui;
+
+import android.graphics.Rect;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * A utility class for working with Views.
+ */
+public final class Views {
+
+    private Views() {}
+
+    /**
+     * Return whether the event is in the view's region
+     * @param event the motion event
+     * @param view the view to check the selection region
+     * @return True, if the event is in the region. Otherwise, return false.
+     */
+    public static boolean isEventOver(MotionEvent event, View view) {
+        if (view == null || event == null || !view.isAttachedToWindow()) {
+            return false;
+        }
+
+        final int[] coord = new int[2];
+        view.getLocationOnScreen(coord);
+
+        final Rect viewRect = new Rect(coord[0], coord[1], coord[0] + view.getMeasuredWidth(),
+                coord[1] + view.getMeasuredHeight());
+
+        return viewRect.contains((int) event.getRawX(), (int) event.getRawY());
+    }
+}
diff --git a/src/com/android/documentsui/util/FormatUtils.java b/src/com/android/documentsui/util/FormatUtils.java
new file mode 100644
index 0000000..f5f8486
--- /dev/null
+++ b/src/com/android/documentsui/util/FormatUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.documentsui.util;
+
+import android.icu.text.MeasureFormat;
+import android.icu.text.MeasureFormat.FormatWidth;
+import android.icu.util.Measure;
+import android.icu.util.MeasureUnit;
+import android.text.format.DateUtils;
+
+import java.util.Locale;
+
+/**
+ * A utility class for formating different type of values to strings.
+ */
+public class FormatUtils {
+    private FormatUtils() {}
+
+    /**
+     * Returns the given duration in a human-friendly format. For example,
+     * "4 minutes" or "1 second". Returns only the largest meaningful unit of time,
+     * and the result duration will round to that unit.
+     * For example, 500 milliseconds round to 1 second,
+     * 90000 milliseconds (90 seconds or 1.5 minutes) round to 2 minutes.
+     * The returned unit of time is from seconds up to hours.
+     * This founction is copied from {@link DateUtils}
+     * @param millis the duration time in milliseconds.
+     * @return String of the duration.
+     */
+    public static String formatDuration(long millis) {
+        MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.WIDE);
+        if (millis >= DateUtils.HOUR_IN_MILLIS) {
+            final int hours =
+                    (int) ((millis + DateUtils.HOUR_IN_MILLIS / 2) / DateUtils.HOUR_IN_MILLIS);
+            return formatter.format(new Measure(hours, MeasureUnit.HOUR));
+        } else if (millis >= DateUtils.MINUTE_IN_MILLIS) {
+            final int minutes =
+                    (int) ((millis + DateUtils.MINUTE_IN_MILLIS / 2) / DateUtils.MINUTE_IN_MILLIS);
+            return formatter.format(new Measure(minutes, MeasureUnit.MINUTE));
+        } else {
+            final int seconds =
+                    (int) ((millis + DateUtils.SECOND_IN_MILLIS / 2) / DateUtils.SECOND_IN_MILLIS);
+            return formatter.format(new Measure(seconds, MeasureUnit.SECOND));
+        }
+    }
+}
diff --git a/tests/Android.bp b/tests/Android.bp
new file mode 100644
index 0000000..92c578d
--- /dev/null
+++ b/tests/Android.bp
@@ -0,0 +1,97 @@
+// Copyright (C) 2019 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.
+
+filegroup {
+    name: "DocumentsUIPerfTests-files",
+    srcs: [
+        "common/com/android/documentsui/**/*.java",
+        "functional/com/android/documentsui/ActivityTest.java",
+    ],
+}
+
+filegroup {
+    name: "DocumentsUITests-srcs",
+    srcs: [
+        "common/**/*.java",
+        "functional/**/*.java",
+        "unit/**/*.java",
+    ],
+}
+
+android_library {
+    name: "DocumentsUITests-res-lib",
+
+    manifest: "AndroidManifest.xml",
+
+    asset_dirs: [
+        "assets",
+    ],
+
+    resource_dirs: [
+        "res",
+    ],
+
+    aaptflags: [
+        // pack some raw file locate in assets folder
+        "-0 .zip",
+        "--auto-add-overlay",
+    ],
+}
+
+android_test {
+    name: "DocumentsUITests",
+
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        "common/**/*.java",
+        "functional/**/*.java",
+        "unit/**/*.java",
+    ],
+
+    resource_dirs: [
+        "res",
+    ],
+
+    aaptflags: [
+        "-0 .zip",
+    ],
+
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+    ],
+
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.espresso.core",
+        "androidx.test.ext.truth",
+        "guava",
+        "mockito-target",
+        "ub-uiautomator",
+    ],
+
+    jarjar_rules: "jarjar-rules.txt",
+
+    test_suites: [
+        "device-tests",
+    ],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    instrumentation_for: "DocumentsUI",
+}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 143e685..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# unittests
-LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, common) \
-    $(call all-java-files-under, unit) \
-    $(call all-java-files-under, functional)
-
-# For testing ZIP files. Include testing ZIP files as uncompresseed raw
-# resources.
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_AAPT_FLAGS += -0 .zip
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    mockito-target \
-    ub-uiautomator \
-    espresso-core \
-    guava
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-LOCAL_PACKAGE_NAME := DocumentsUITests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_INSTRUMENTATION_FOR := DocumentsUI
-LOCAL_CERTIFICATE := platform
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 1b6dfba..698da33 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -135,7 +135,7 @@
 
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.documentsui"
         android:label="Tests for DocumentsUI" />
 
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 07968ae..7893150 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -22,7 +22,7 @@
     <option name="test-tag" value="DocumentsUITests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.documentsui.tests" />
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/README b/tests/README
index 7112376..d8ea236 100644
--- a/tests/README
+++ b/tests/README
@@ -8,6 +8,6 @@
 and uses it instead.
 
 To run just small tests"
-adb shell am instrument -w -e debug false -e log false -e timeout_msec 300000 -e size small com.android.documentsui.tests/android.support.test.runner.AndroidJUnitRunner
+adb shell am instrument -w -e debug false -e log false -e timeout_msec 300000 -e size small com.android.documentsui.tests/androidx.test.runner.AndroidJUnitRunner
 
 Replace '-e size small' with '-e size large'.
diff --git a/tests/assets/archives/7z/hello.7z b/tests/assets/archives/7z/hello.7z
new file mode 100644
index 0000000..249330b
--- /dev/null
+++ b/tests/assets/archives/7z/hello.7z
Binary files differ
diff --git a/tests/assets/archives/7z/hello.tar.7z b/tests/assets/archives/7z/hello.tar.7z
new file mode 100644
index 0000000..3c70be1
--- /dev/null
+++ b/tests/assets/archives/7z/hello.tar.7z
Binary files differ
diff --git a/tests/assets/archives/ar/hello.ar b/tests/assets/archives/ar/hello.ar
new file mode 100644
index 0000000..382610c
--- /dev/null
+++ b/tests/assets/archives/ar/hello.ar
@@ -0,0 +1,29 @@
+!<arch>
+hello.txt/      1536306572  52434389939 100644  48        `
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+hello2.txt/     1536306572  52434389939 100644  48        `
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
diff --git a/tests/assets/archives/brotli/hello.tar.br b/tests/assets/archives/brotli/hello.tar.br
new file mode 100644
index 0000000..1104a25
--- /dev/null
+++ b/tests/assets/archives/brotli/hello.tar.br
Binary files differ
diff --git a/tests/assets/archives/cpio/hello.cpio b/tests/assets/archives/cpio/hello.cpio
new file mode 100644
index 0000000..9dad256
--- /dev/null
+++ b/tests/assets/archives/cpio/hello.cpio
Binary files differ
diff --git a/tests/assets/archives/lzma/hello.tar.lzma b/tests/assets/archives/lzma/hello.tar.lzma
new file mode 100644
index 0000000..334aaaf
--- /dev/null
+++ b/tests/assets/archives/lzma/hello.tar.lzma
Binary files differ
diff --git a/tests/assets/archives/lzo/hello.tar.lzo b/tests/assets/archives/lzo/hello.tar.lzo
new file mode 100644
index 0000000..a0b070a
--- /dev/null
+++ b/tests/assets/archives/lzo/hello.tar.lzo
Binary files differ
diff --git a/tests/assets/archives/original/hello/hello.txt b/tests/assets/archives/original/hello/hello.txt
new file mode 100644
index 0000000..47b3ac3
--- /dev/null
+++ b/tests/assets/archives/original/hello/hello.txt
@@ -0,0 +1,13 @@
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
diff --git a/tests/assets/archives/original/hello/hello2.txt b/tests/assets/archives/original/hello/hello2.txt
new file mode 100644
index 0000000..47b3ac3
--- /dev/null
+++ b/tests/assets/archives/original/hello/hello2.txt
@@ -0,0 +1,13 @@
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
+
+hello
diff --git a/tests/assets/archives/original/hello/inside_folder/hello_insside.txt b/tests/assets/archives/original/hello/inside_folder/hello_insside.txt
new file mode 100644
index 0000000..8c857bf
--- /dev/null
+++ b/tests/assets/archives/original/hello/inside_folder/hello_insside.txt
@@ -0,0 +1,2 @@
+hello inside
+
diff --git a/tests/assets/archives/tar/hello.tar b/tests/assets/archives/tar/hello.tar
new file mode 100644
index 0000000..cdc2310
--- /dev/null
+++ b/tests/assets/archives/tar/hello.tar
Binary files differ
diff --git a/tests/assets/archives/tar_bz2/hello.tar.bz2 b/tests/assets/archives/tar_bz2/hello.tar.bz2
new file mode 100644
index 0000000..37464da
--- /dev/null
+++ b/tests/assets/archives/tar_bz2/hello.tar.bz2
Binary files differ
diff --git a/tests/assets/archives/tar_gz/hello.tgz b/tests/assets/archives/tar_gz/hello.tgz
new file mode 100644
index 0000000..93f0194
--- /dev/null
+++ b/tests/assets/archives/tar_gz/hello.tgz
Binary files differ
diff --git a/tests/assets/archives/tar_gz/hello_tar_gz b/tests/assets/archives/tar_gz/hello_tar_gz
new file mode 100644
index 0000000..93f0194
--- /dev/null
+++ b/tests/assets/archives/tar_gz/hello_tar_gz
Binary files differ
diff --git a/tests/assets/archives/xz/hello.tar.xz b/tests/assets/archives/xz/hello.tar.xz
new file mode 100644
index 0000000..5b5f750
--- /dev/null
+++ b/tests/assets/archives/xz/hello.tar.xz
Binary files differ
diff --git a/tests/assets/archives/zip/hello.zip b/tests/assets/archives/zip/hello.zip
new file mode 100644
index 0000000..a282420
--- /dev/null
+++ b/tests/assets/archives/zip/hello.zip
Binary files differ
diff --git a/tests/common/com/android/documentsui/DocumentsProviderHelper.java b/tests/common/com/android/documentsui/DocumentsProviderHelper.java
index f0e6d12..e7a590e 100644
--- a/tests/common/com/android/documentsui/DocumentsProviderHelper.java
+++ b/tests/common/com/android/documentsui/DocumentsProviderHelper.java
@@ -16,11 +16,12 @@
 
 package com.android.documentsui;
 
+import static android.content.ContentResolver.wrap;
 import static android.provider.DocumentsContract.buildChildDocumentsUri;
 import static android.provider.DocumentsContract.buildDocumentUri;
 import static android.provider.DocumentsContract.buildRootsUri;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
-import static com.android.internal.util.Preconditions.checkArgument;
+import static androidx.core.util.Preconditions.checkArgument;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.fail;
@@ -36,7 +37,7 @@
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.test.MoreAsserts;
 import android.text.TextUtils;
 
@@ -44,13 +45,15 @@
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.roots.RootCursorWrapper;
 
-import com.google.android.collect.Lists;
-
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 import libcore.io.Streams;
 
+import com.google.common.collect.Lists;
+
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -81,7 +84,7 @@
         } catch (Exception e) {
             throw new RuntimeException("Can't load root for id=" + documentId , e);
         } finally {
-            IoUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(cursor);
         }
     }
 
@@ -90,9 +93,9 @@
             throw new IllegalArgumentException("Name and mimetype probably interposed.");
         }
         try {
-            Uri uri = DocumentsContract.createDocument(mClient, parentUri, mimeType, name);
+            Uri uri = DocumentsContract.createDocument(wrap(mClient), parentUri, mimeType, name);
             return uri;
-        } catch (RemoteException e) {
+        } catch (FileNotFoundException e) {
             throw new RuntimeException("Couldn't create document: " + name + " with mimetype "
                     + mimeType, e);
         }
@@ -352,7 +355,7 @@
         } catch (Exception e) {
             throw new RuntimeException("Can't load rootInfo list", e);
         } finally {
-            IoUtils.closeQuietly(cursor);
+            FileUtils.closeQuietly(cursor);
         }
         return list;
     }
diff --git a/tests/common/com/android/documentsui/InspectorProvider.java b/tests/common/com/android/documentsui/InspectorProvider.java
index 8db6b2b..1d678d1 100644
--- a/tests/common/com/android/documentsui/InspectorProvider.java
+++ b/tests/common/com/android/documentsui/InspectorProvider.java
@@ -15,12 +15,18 @@
  */
 package com.android.documentsui;
 
+import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_METADATA;
 import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_SETTINGS;
 
+import android.content.Context;
+import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.database.MatrixCursor.RowBuilder;
+import android.media.ExifInterface;
+import android.os.Bundle;
 import android.provider.DocumentsContract.Document;
+
 import java.io.FileNotFoundException;
 
 /**
@@ -32,12 +38,24 @@
  *         openInProvider    Dummy1 50B      Dummy11 50B     Dummy22 150B
  *         test.txt          Dummy2 150B     Dummy12 150B    Dummy23 100B
  *         update.txt        Dummy3 100B     Dummy13 100B
+ *         test.jpg
+ *         invalid.jpg
  */
 public class InspectorProvider extends TestRootProvider {
 
     public static final String AUTHORITY = "com.android.documentsui.inspectorprovider";
     public static final String OPEN_IN_PROVIDER_TEST = "OpenInProviderTest";
     public static final String ROOT_ID = "inspector-root";
+    // Number of items under the root path of InspectorProvider.
+    public static final String NUMBER_OF_ITEMS = "6";
+    // Virtual jpeg files for test metadata loading from provider.
+    // TEST_JPEG is a normal jpeg file with legal exif data.
+    // INVALID_JPEG is a invalid jpeg file with broken exif data.
+    // TEST_JPEG_WIDTH, TEST_JPEG_HEIGHT are exif information for TEST_JPEG.
+    public static final String TEST_JPEG = "test.jpg";
+    public static final String INVALID_JPEG = "invalid.jpg";
+    public static final int TEST_JPEG_WIDTH = 3840;
+    public static final int TEST_JPEG_HEIGHT = 2160;
 
     private static final String ROOT_DOC_ID = "root0";
     private static final int ROOT_FLAGS = 0;
@@ -62,6 +80,17 @@
     }
 
     @Override
+    public void attachInfo(Context context, ProviderInfo info) {
+        // prevent the testing from Security Exception comes from DocumentsProvider
+        info.exported = true;
+        info.grantUriPermissions = true;
+        info.writePermission = android.Manifest.permission.MANAGE_DOCUMENTS;
+        info.readPermission = android.Manifest.permission.MANAGE_DOCUMENTS;
+
+        super.attachInfo(context, info);
+    }
+
+    @Override
     public Cursor queryChildDocuments(String s, String[] projection, String s1)
             throws FileNotFoundException {
 
@@ -90,10 +119,14 @@
         }
         else {
             MatrixCursor c = createDocCursor(projection);
+            // If you add folder or file here, please modify NUMBER_OF_ITEMS above for
+            // #testFolderDetails in InspectorUiTest accordingly.
             addFolder(c, "Top");
             addFile(c, OPEN_IN_PROVIDER_TEST, FLAG_SUPPORTS_SETTINGS);
             addFile(c, "test.txt");
             addFile(c, "update.txt");
+            addFile(c, TEST_JPEG, FLAG_SUPPORTS_METADATA);
+            addFile(c, INVALID_JPEG, FLAG_SUPPORTS_METADATA);
             return c;
         }
     }
@@ -108,6 +141,20 @@
         row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
     }
 
+    @Override
+    public Bundle getDocumentMetadata(String documentId) throws FileNotFoundException {
+        if (TEST_JPEG.contentEquals(documentId)) {
+            Bundle metaData = new Bundle();
+            metaData.putInt(ExifInterface.TAG_IMAGE_WIDTH, TEST_JPEG_WIDTH);
+            metaData.putInt(ExifInterface.TAG_IMAGE_LENGTH, TEST_JPEG_HEIGHT);
+            return metaData;
+        } else if (INVALID_JPEG.contentEquals(documentId)) {
+            // Suppose there are some errors occurs.
+            // Return null makes DocumentsContract throw a RemoteExcpetion,
+            // and rethrow a RemoteException when using ContentResolver.
+            return null;
+        }
 
-
+        return super.getDocumentMetadata(documentId);
+    }
 }
diff --git a/tests/common/com/android/documentsui/SelectionHelpers.java b/tests/common/com/android/documentsui/SelectionHelpers.java
new file mode 100644
index 0000000..2018252
--- /dev/null
+++ b/tests/common/com/android/documentsui/SelectionHelpers.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 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.documentsui;
+
+import androidx.recyclerview.selection.DefaultSelectionTracker;
+import androidx.recyclerview.selection.SelectionPredicates;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.SelectionTracker.SelectionPredicate;
+import androidx.recyclerview.selection.StorageStrategy;
+
+import com.android.documentsui.testing.TestStableIdProvider;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SelectionHelpers {
+
+    public static final SelectionPredicate<String> CAN_SET_ANYTHING =
+            SelectionPredicates.createSelectAnything();
+
+    private SelectionHelpers() {}
+
+    public static DocsSelectionHelper createTestInstance() {
+        return createTestInstance(Collections.emptyList());
+    }
+
+    public static DocsSelectionHelper createTestInstance(List<String> docs) {
+        DocsSelectionHelper manager = new DocsSelectionHelper(
+                new DocsSelectionHelper.DelegateFactory() {
+
+                    @Override
+                    SelectionTracker<String> create(SelectionTracker<String> selectionTracker) {
+                        return new DefaultSelectionTracker<String>(
+                                Integer.toHexString(System.identityHashCode(docs)),
+                                new TestStableIdProvider(docs),
+                                CAN_SET_ANYTHING,
+                                StorageStrategy.createStringStorage());
+                    }
+                });
+
+        manager.reset(null);
+        return manager;
+    }
+}
diff --git a/tests/common/com/android/documentsui/StubProvider.java b/tests/common/com/android/documentsui/StubProvider.java
index 8f5378d..4366d31 100644
--- a/tests/common/com/android/documentsui/StubProvider.java
+++ b/tests/common/com/android/documentsui/StubProvider.java
@@ -31,11 +31,11 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsProvider;
-import android.support.annotation.VisibleForTesting;
+import androidx.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.Log;
 
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -472,8 +472,8 @@
                 Log.e(TAG, "Error on close", e);
                 closePipeWithErrorSilently(readPipe, e.getMessage());
             } finally {
-                IoUtils.closeQuietly(inputStream);
-                IoUtils.closeQuietly(outputStream);
+                FileUtils.closeQuietly(inputStream);
+                FileUtils.closeQuietly(outputStream);
                 Log.d(TAG, "Closing write stream on file " + document.documentId);
                 notifyParentChanged(document.parentId);
                 getContext().getContentResolver().notifyChange(
diff --git a/tests/common/com/android/documentsui/TestActivity.java b/tests/common/com/android/documentsui/TestActivity.java
index 13abf1e..103fb40 100644
--- a/tests/common/com/android/documentsui/TestActivity.java
+++ b/tests/common/com/android/documentsui/TestActivity.java
@@ -18,8 +18,9 @@
 
 import static junit.framework.Assert.assertEquals;
 
-import android.annotation.Nullable;
-import android.app.Activity;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
 import android.app.ActivityManager;
 import android.app.LoaderManager;
 import android.content.ComponentName;
@@ -42,6 +43,7 @@
 import com.android.documentsui.testing.TestLoaderManager;
 import com.android.documentsui.testing.TestPackageManager;
 import com.android.documentsui.testing.TestResources;
+import com.android.documentsui.testing.TestSupportLoaderManager;
 
 import org.mockito.Mockito;
 
@@ -57,6 +59,7 @@
     public RootInfo currentRoot;
     public MockContentResolver contentResolver;
     public TestLoaderManager loaderManager;
+    public TestSupportLoaderManager supportLoaderManager;
     public ActivityManager activityManager;
 
     public TestEventListener<Intent> startActivity;
@@ -90,6 +93,7 @@
         notifyDirectoryNavigated = new TestEventListener<>();
         contentResolver = env.contentResolver;
         loaderManager = new TestLoaderManager();
+        supportLoaderManager = new TestSupportLoaderManager();
         finishedHandler = new TestEventHandler<>();
     }
 
@@ -198,6 +202,11 @@
     }
 
     @Override
+    public final androidx.loader.app.LoaderManager getSupportLoaderManager() {
+        return supportLoaderManager;
+    }
+
+    @Override
     public final Object getSystemService(String service) {
         switch (service) {
             case Context.ACTIVITY_SERVICE:
@@ -215,4 +224,4 @@
 
 // Trick Mockito into finding our Addons methods correctly. W/o this
 // hack, Mockito thinks Addons methods are not implemented.
-abstract class AbstractBase extends Activity implements CommonAddons {}
+abstract class AbstractBase extends FragmentActivity implements CommonAddons {}
diff --git a/tests/common/com/android/documentsui/bots/Bots.java b/tests/common/com/android/documentsui/bots/Bots.java
index 430309a..3e43a69 100644
--- a/tests/common/com/android/documentsui/bots/Bots.java
+++ b/tests/common/com/android/documentsui/bots/Bots.java
@@ -28,6 +28,8 @@
 import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 
+import androidx.test.InstrumentationRegistry;
+
 /**
  * Handy collection of bots for working with Files app.
  */
@@ -37,7 +39,7 @@
 
     public final BreadBot breadcrumb;
     public final DirectoryListBot directory;
-    public final SortHeaderBot sortHeader;
+    public final SortBot sort;
     public final KeyboardBot keyboard;
     public final SidebarBot roots;
     public final SearchBot search;
@@ -52,7 +54,7 @@
         breadcrumb = new BreadBot(device, context, TIMEOUT, main);
         roots = new SidebarBot(device, context, TIMEOUT);
         directory = new DirectoryListBot(device, automation, context, TIMEOUT);
-        sortHeader = new SortHeaderBot(device, context, TIMEOUT);
+        sort = new SortBot(device, context, TIMEOUT, main);
         keyboard = new KeyboardBot(device, context, TIMEOUT);
         search = new SearchBot(device, context, TIMEOUT);
         gesture = new GestureBot(device, automation, context, TIMEOUT);
@@ -69,11 +71,15 @@
         public final UiDevice mDevice;
         final Context mContext;
         final int mTimeout;
+        public final String mTargetPackage;
 
         BaseBot(UiDevice device, Context context, int timeout) {
             mDevice = device;
             mContext = context;
             mTimeout = timeout;
+            mTargetPackage =
+                    InstrumentationRegistry.getInstrumentation()
+                            .getTargetContext().getPackageName();
         }
 
         /**
diff --git a/tests/common/com/android/documentsui/bots/BreadBot.java b/tests/common/com/android/documentsui/bots/BreadBot.java
index 7ec64e2..c90899b 100644
--- a/tests/common/com/android/documentsui/bots/BreadBot.java
+++ b/tests/common/com/android/documentsui/bots/BreadBot.java
@@ -16,23 +16,25 @@
 
 package com.android.documentsui.bots;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
 import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.anyOf;
 import static org.hamcrest.CoreMatchers.is;
 
 import android.content.Context;
-import android.support.test.espresso.ViewInteraction;
-import android.support.test.espresso.matcher.BoundedMatcher;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObjectNotFoundException;
 import android.view.View;
 
+import androidx.test.espresso.ViewInteraction;
+import androidx.test.espresso.matcher.BoundedMatcher;
+
 import com.android.documentsui.DragOverTextView;
 import com.android.documentsui.DropdownBreadcrumb;
 import com.android.documentsui.R;
@@ -56,8 +58,6 @@
  */
 public class BreadBot extends Bots.BaseBot {
 
-    public static final String TARGET_PKG = "com.android.documentsui";
-
     private static final Matcher<View> DROPDOWN_BREADCRUMB = withId(
             R.id.dropdown_breadcrumb);
 
diff --git a/tests/common/com/android/documentsui/bots/DirectoryListBot.java b/tests/common/com/android/documentsui/bots/DirectoryListBot.java
index beeffdc..97db4de 100644
--- a/tests/common/com/android/documentsui/bots/DirectoryListBot.java
+++ b/tests/common/com/android/documentsui/bots/DirectoryListBot.java
@@ -52,17 +52,27 @@
  * and making assertions against the state of it.
  */
 public class DirectoryListBot extends Bots.BaseBot {
-    private static final String DIR_CONTAINER_ID = "com.android.documentsui:id/container_directory";
-    private static final String DIR_LIST_ID = "com.android.documentsui:id/dir_list";
+
+    private static final int MAX_LAYOUT_LEVEL = 10;
 
     private static final BySelector SNACK_DELETE =
-            By.desc(Pattern.compile("^Deleting [0-9]+ file.+"));
+            By.text(Pattern.compile("^Deleting [0-9]+ item.+"));
+
+    private final String mDirContainerId;
+    private final String mDirListId;
+    private final String mItemRootId;
+    private final String mPreviewId;
+
     private UiAutomation mAutomation;
 
     public DirectoryListBot(
             UiDevice device, UiAutomation automation, Context context, int timeout) {
         super(device, context, timeout);
         mAutomation = automation;
+        mDirContainerId = mTargetPackage + ":id/container_directory";
+        mDirListId = mTargetPackage + ":id/dir_list";
+        mItemRootId = mTargetPackage + ":id/item_root";
+        mPreviewId = mTargetPackage + ":id/preview_icon";
     }
 
     public void assertDocumentsCount(int count) throws UiObjectNotFoundException {
@@ -122,7 +132,7 @@
     public void assertHasMessageButtonText(String expected) throws UiObjectNotFoundException {
         UiObject button = findHeaderMessageButton();
         String msg = String.valueOf(expected);
-        assertEquals(msg, button.getText());
+        assertEquals(msg.toUpperCase(), button.getText().toUpperCase());
     }
 
     public void clickMessageButton() throws UiObjectNotFoundException {
@@ -145,20 +155,24 @@
 
     private UiObject findHeaderMessageTextView() {
         return findObject(
-                DIR_CONTAINER_ID,
-                "com.android.documentsui:id/message_textview");
+                mDirContainerId,
+                mTargetPackage + ":id/message_textview");
     }
 
     private UiObject findHeaderMessageButton() {
         return findObject(
-                DIR_CONTAINER_ID,
-                "com.android.documentsui:id/button_dismiss");
+                mDirContainerId,
+                mTargetPackage + ":id/button_dismiss");
     }
 
     private UiObject findPlaceholderMessageTextView() {
         return findObject(
-                DIR_CONTAINER_ID,
-                "com.android.documentsui:id/message");
+                mDirContainerId,
+                mTargetPackage + ":id/message");
+    }
+
+    public void waitForHolderMessage() {
+        findPlaceholderMessageTextView().waitForExists(mTimeout);
     }
 
     public void assertSnackbar(int id) {
@@ -191,14 +205,22 @@
         assertSelection(number);
     }
 
+    public boolean isDocumentSelected(String label) throws UiObjectNotFoundException {
+        waitForDocument(label);
+        UiObject2 selectionHotspot = findSelectionHotspot(label);
+        return selectionHotspot.getResourceName()
+                .equals(mTargetPackage + ":id/icon_check");
+    }
+
     public UiObject2 findSelectionHotspot(String label) {
-        final BySelector list = By.res(DIR_LIST_ID);
+        final BySelector list = By.res(mDirListId);
 
         BySelector selector = By.hasChild(By.text(label));
         UiObject2 parent = mDevice.findObject(list).findObject(selector);
-        if (parent.getClassName().equals("android.widget.LinearLayout")) {
-            // For list mode, the parent of the textView does not contain the selector icon, but the
-            // grandparent of the textView does
+        if (parent.getClassName().equals("android.widget.LinearLayout")
+                || parent.getClassName().equals("android.widget.RelativeLayout")) {
+            // For list mode and doc grid, the parent of the textView does not contain the selector
+            // icon, but the grandparent of the textView does
             // Gotta go one more level up
             selector = By.hasDescendant(By.text(label).depth(2));
             parent = mDevice.findObject(list).findObject(selector);
@@ -221,6 +243,12 @@
         return mDevice.wait(Until.findObject(By.text(message)), mTimeout);
     }
 
+    public void clickSnackbarAction() throws UiObjectNotFoundException {
+        UiObject snackbarAction =
+                findObject(mTargetPackage + ":id/snackbar_action");
+        snackbarAction.click();
+    }
+
     public void waitForDeleteSnackbar() {
         mDevice.wait(Until.findObject(SNACK_DELETE), mTimeout);
     }
@@ -236,8 +264,8 @@
 
     public UiObject findDocument(String label) throws UiObjectNotFoundException {
         final UiSelector docList = new UiSelector().resourceId(
-                DIR_CONTAINER_ID).childSelector(
-                        new UiSelector().resourceId(DIR_LIST_ID));
+                mDirContainerId).childSelector(
+                        new UiSelector().resourceId(mDirListId));
 
         // Wait for the first list item to appear
         new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout);
@@ -255,10 +283,25 @@
         return true;
     }
 
+    public boolean hasDocumentPreview(String label) {
+        final BySelector list = By.res(mDirListId);
+        final UiObject2 text = mDevice.findObject(list).findObject(By.text(label));
+
+        UiObject2 parent = text;
+        for (int i = 1; i <= MAX_LAYOUT_LEVEL; i++) {
+            parent = parent.getParent();
+            if (mItemRootId.equals(parent.getResourceName())) {
+                break;
+            }
+        }
+
+        return parent.hasObject(By.res(mPreviewId));
+    }
+
     public void assertFirstDocumentHasFocus() throws UiObjectNotFoundException {
         final UiSelector docList = new UiSelector().resourceId(
-                DIR_CONTAINER_ID).childSelector(
-                        new UiSelector().resourceId(DIR_LIST_ID));
+                mDirContainerId).childSelector(
+                        new UiSelector().resourceId(mDirListId));
 
         // Wait for the first list item to appear
         UiObject doc = new UiObject(docList.childSelector(new UiSelector()));
@@ -269,12 +312,12 @@
 
     public UiObject findDocumentsList() {
         return findObject(
-                DIR_CONTAINER_ID,
-                DIR_LIST_ID);
+                mDirContainerId,
+                mDirListId);
     }
 
     public void assertHasFocus() {
-        assertHasFocus(DIR_LIST_ID);
+        assertHasFocus(mDirListId);
     }
 
     public void assertSelection(int numSelected) {
diff --git a/tests/common/com/android/documentsui/bots/GestureBot.java b/tests/common/com/android/documentsui/bots/GestureBot.java
index e0ca8b6..9a0fb6e 100644
--- a/tests/common/com/android/documentsui/bots/GestureBot.java
+++ b/tests/common/com/android/documentsui/bots/GestureBot.java
@@ -36,19 +36,22 @@
  * and making assertions against the state of it.
  */
 public class GestureBot extends Bots.BaseBot {
-    private static final String DIR_CONTAINER_ID = "com.android.documentsui:id/container_directory";
-    private static final String DIR_LIST_ID = "com.android.documentsui:id/dir_list";
     private static final int LONGPRESS_STEPS = 60;
     private static final int TRAVELING_STEPS = 20;
     private static final int BAND_SELECTION_DEFAULT_STEPS = 100;
     private static final int STEPS_INBETWEEN_POINTS = 2;
     // Inserted after each motion event injection.
     private static final int MOTION_EVENT_INJECTION_DELAY_MILLIS = 5;
+    private static final int LONG_PRESS_EVENT_INJECTION_DELAY_MILIS = 1000;
+    private final String mDirContainerId;
+    private final String mDirListId;
     private final UiAutomation mAutomation;
     private long mDownTime = 0;
 
     public GestureBot(UiDevice device, UiAutomation automation, Context context, int timeout) {
         super(device, context, timeout);
+        mDirContainerId = mTargetPackage + ":id/container_directory";
+        mDirListId = mTargetPackage + ":id/dir_list";
         mAutomation = automation;
     }
 
@@ -80,17 +83,28 @@
         bandSelection(start, end, BAND_SELECTION_DEFAULT_STEPS);
     }
 
+    public void fingerSelection(Point start, Point end) throws Exception {
+        fingerSelection(start, end, BAND_SELECTION_DEFAULT_STEPS);
+    }
+
     public void bandSelection(Point start, Point end, int steps) throws Exception {
         int toolType = Configurator.getInstance().getToolType();
         Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
-        swipe(start.x, start.y, end.x, end.y, steps, MotionEvent.BUTTON_PRIMARY);
+        swipe(start.x, start.y, end.x, end.y, steps, MotionEvent.BUTTON_PRIMARY, false);
+        Configurator.getInstance().setToolType(toolType);
+    }
+
+    private void fingerSelection(Point start, Point end, int steps) throws Exception {
+        int toolType = Configurator.getInstance().getToolType();
+        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
+        swipe(start.x, start.y, end.x, end.y, steps, MotionEvent.BUTTON_PRIMARY, true);
         Configurator.getInstance().setToolType(toolType);
     }
 
     public UiObject findDocument(String label) throws UiObjectNotFoundException {
         final UiSelector docList = new UiSelector().resourceId(
-                DIR_CONTAINER_ID).childSelector(
-                        new UiSelector().resourceId(DIR_LIST_ID));
+                mDirContainerId).childSelector(
+                new UiSelector().resourceId(mDirListId));
 
         // Wait for the first list item to appear
         new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout);
@@ -98,22 +112,27 @@
         return mDevice.findObject(docList.childSelector(new UiSelector().text(label)));
     }
 
-    private void swipe(int downX, int downY, int upX, int upY, int steps, int button) {
+    private void swipe(int downX, int downY, int upX, int upY, int steps, int button,
+            boolean fingerSelection) {
         int swipeSteps = steps;
         double xStep = 0;
         double yStep = 0;
 
         // avoid a divide by zero
-        if(swipeSteps == 0)
+        if (swipeSteps == 0) {
             swipeSteps = 1;
+        }
 
-        xStep = ((double)(upX - downX)) / swipeSteps;
-        yStep = ((double)(upY - downY)) / swipeSteps;
+        xStep = ((double) (upX - downX)) / swipeSteps;
+        yStep = ((double) (upY - downY)) / swipeSteps;
 
         // first touch starts exactly at the point requested
         touchDown(downX, downY, button);
-        for(int i = 1; i < swipeSteps; i++) {
-            touchMove(downX + (int)(xStep * i), downY + (int)(yStep * i), button);
+        if (fingerSelection) {
+            SystemClock.sleep(LONG_PRESS_EVENT_INJECTION_DELAY_MILIS);
+        }
+        for (int i = 1; i < swipeSteps; i++) {
+            touchMove(downX + (int) (xStep * i), downY + (int) (yStep * i), button);
             // set some known constant delay between steps as without it this
             // become completely dependent on the speed of the system and results
             // may vary on different devices. This guarantees at minimum we have
@@ -159,7 +178,7 @@
         coords.y = y;
 
         return MotionEvent.obtain(downTime, eventTime, action, 1,
-                new PointerProperties[] { properties }, new PointerCoords[] { coords },
+                new PointerProperties[]{properties}, new PointerCoords[]{coords},
                 0, button, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
     }
 }
diff --git a/tests/common/com/android/documentsui/bots/InspectorBot.java b/tests/common/com/android/documentsui/bots/InspectorBot.java
index 448a7b7..252fde4 100644
--- a/tests/common/com/android/documentsui/bots/InspectorBot.java
+++ b/tests/common/com/android/documentsui/bots/InspectorBot.java
@@ -41,8 +41,10 @@
     }
 
     public void assertTitle(String expected) throws Exception {
-        UiSelector textView
-                = new UiSelector().resourceId("com.android.documentsui:id/inspector_file_title");
+        UiSelector detailView =
+                new UiSelector().resourceId(mTargetPackage + ":id/inspector_details_view");
+        UiSelector textView =
+                detailView.resourceId(mTargetPackage + ":id/inspector_header_title");
         String text = mDevice.findObject(textView).getText();
         assertEquals(expected, text);
     }
diff --git a/tests/common/com/android/documentsui/bots/KeyboardBot.java b/tests/common/com/android/documentsui/bots/KeyboardBot.java
index 2e71577..6167acf 100644
--- a/tests/common/com/android/documentsui/bots/KeyboardBot.java
+++ b/tests/common/com/android/documentsui/bots/KeyboardBot.java
@@ -16,9 +16,9 @@
 
 package com.android.documentsui.bots;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.pressImeActionButton;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.pressImeActionButton;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
 
 import android.content.Context;
 import android.support.test.uiautomator.UiDevice;
diff --git a/tests/common/com/android/documentsui/bots/Matchers.java b/tests/common/com/android/documentsui/bots/Matchers.java
index 9d33adc..9fc676e 100644
--- a/tests/common/com/android/documentsui/bots/Matchers.java
+++ b/tests/common/com/android/documentsui/bots/Matchers.java
@@ -16,13 +16,14 @@
 
 package com.android.documentsui.bots;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
 
-import android.support.test.espresso.ViewInteraction;
 import android.view.View;
 
+import androidx.test.espresso.ViewInteraction;
+
 import junit.framework.AssertionFailedError;
 
 import org.hamcrest.Matcher;
diff --git a/tests/common/com/android/documentsui/bots/MenuBot.java b/tests/common/com/android/documentsui/bots/MenuBot.java
index 06e5054..511c51e 100644
--- a/tests/common/com/android/documentsui/bots/MenuBot.java
+++ b/tests/common/com/android/documentsui/bots/MenuBot.java
@@ -40,6 +40,10 @@
         return mDevice.findObject(By.text(menuLabel)) != null;
     }
 
+    public boolean hasMenuItemByDesc(String menuDesc) throws UiObjectNotFoundException {
+        return mDevice.findObject(By.desc(menuDesc)) != null;
+    }
+
     public void assertPresentMenuItems(Map<String, Boolean> menuStates) throws Exception {
         for (String key : menuStates.keySet()) {
             if (menuStates.get(key)) {
diff --git a/tests/common/com/android/documentsui/bots/NotificationsBot.java b/tests/common/com/android/documentsui/bots/NotificationsBot.java
index 500b630..5ab872d 100644
--- a/tests/common/com/android/documentsui/bots/NotificationsBot.java
+++ b/tests/common/com/android/documentsui/bots/NotificationsBot.java
@@ -17,74 +17,35 @@
 package com.android.documentsui.bots;
 
 import android.app.Activity;
-import android.content.ContentResolver;
+import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiSelector;
-import android.text.TextUtils;
-import android.view.KeyEvent;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.documentsui.services.TestNotificationService;
+
+import java.io.IOException;
 
 /**
  * A test helper class for controlling notification items.
  */
 public class NotificationsBot extends Bots.BaseBot {
-    private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
-    private static final String allow_res_name = "allow";
-    private static final String turn_off_res_name = "notification_listener_disable_warning_confirm";
+    private final ComponentName mComponent;
 
     public NotificationsBot(UiDevice device, Context context, int timeout) {
         super(device, context, timeout);
+        mComponent = new ComponentName(InstrumentationRegistry.getContext(),
+                TestNotificationService.class);
     }
 
-    public void setNotificationAccess(Activity activity, boolean enabled)
-            throws UiObjectNotFoundException, NameNotFoundException {
-        Context testContext = InstrumentationRegistry.getContext();
-
-        if(isNotificationAccessEnabled(
-                mContext.getContentResolver(), testContext.getPackageName()) == enabled) {
-            return;
+    public void setNotificationAccess(Activity activity, boolean enabled) throws IOException {
+        if (enabled) {
+            mDevice.executeShellCommand(
+                    "cmd notification allow_listener " + mComponent.flattenToString());
+        } else {
+            mDevice.executeShellCommand(
+                    "cmd notification disallow_listener " + mComponent.flattenToString());
         }
-
-        Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
-        activity.startActivity(intent);
-        mDevice.waitForIdle();
-
-        String appName = testContext.getPackageManager().getApplicationLabel(
-                testContext.getApplicationInfo()).toString();
-        clickLabel(appName);
-
-        Context settings_context = mContext.createPackageContext(SETTINGS_PACKAGE_NAME,
-                Context.CONTEXT_RESTRICTED);
-        String label_res_name = enabled ? allow_res_name : turn_off_res_name;
-        int res_id = settings_context.getResources().getIdentifier(label_res_name,
-                "string", SETTINGS_PACKAGE_NAME);
-
-        clickLabel(settings_context.getResources().getString(res_id));
-        mDevice.pressKeyCode(KeyEvent.KEYCODE_BACK);
-        mDevice.waitForIdle();
-    }
-
-    private boolean isNotificationAccessEnabled(ContentResolver resolver, String pkgName) {
-        String listeners = Settings.Secure.getString(resolver, "enabled_notification_listeners");
-        if (!TextUtils.isEmpty(listeners)) {
-            String[] list = listeners.split(":");
-            for(String item : list) {
-                if(item.startsWith(pkgName)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private void clickLabel(String label) throws UiObjectNotFoundException {
-        UiSelector selector = new UiSelector().textMatches("(?i)" + label);
-        mDevice.findObject(selector).click();
-        mDevice.waitForIdle();
     }
 }
diff --git a/tests/common/com/android/documentsui/bots/SearchBot.java b/tests/common/com/android/documentsui/bots/SearchBot.java
index f353eb5..9c3568b 100644
--- a/tests/common/com/android/documentsui/bots/SearchBot.java
+++ b/tests/common/com/android/documentsui/bots/SearchBot.java
@@ -16,15 +16,17 @@
 
 package com.android.documentsui.bots;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.typeText;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.isClickable;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.typeText;
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static androidx.test.espresso.matcher.ViewMatchers.isClickable;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
+
 import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.anyOf;
 
@@ -32,9 +34,10 @@
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.v7.recyclerview.R;
 import android.view.View;
 
+import androidx.recyclerview.R;
+
 import org.hamcrest.Matcher;
 
 /**
@@ -45,8 +48,6 @@
  */
 public class SearchBot extends Bots.BaseBot {
 
-    public static final String TARGET_PKG = "com.android.documentsui";
-
     // Dumb search layout changes substantially between Ryu and Angler.
     @SuppressWarnings("unchecked")
     private static final Matcher<View> SEARCH_WIDGET = allOf(
@@ -58,7 +59,7 @@
     // require this input be not clickable.
     @SuppressWarnings("unchecked")
     private static final Matcher<View> SEARCH_INPUT = allOf(
-            withId(R.id.option_menu_search),
+            withId(R.id.search_src_text),
             isDisplayed());
 
     public SearchBot(UiDevice device, Context context, int timeout) {
@@ -68,7 +69,19 @@
     public void clickIcon() throws UiObjectNotFoundException {
         UiObject searchView = findSearchView();
         searchView.click();
-        assertTrue(searchView.exists());
+
+        UiObject fragmentSearchView = findFragmentSearchView();
+        assertTrue(fragmentSearchView.exists());
+    }
+
+    public void clickSearchViewClearButton() throws UiObjectNotFoundException {
+        UiObject clear = findSearchViewClearButton();
+        clear.click();
+    }
+
+    public void clickFragmentSearchViewClearButton() throws UiObjectNotFoundException {
+        UiObject clear = findFragmentSearchClearButton();
+        clear.click();
     }
 
     public void setInputText(String query) throws UiObjectNotFoundException {
@@ -108,17 +121,51 @@
         assertEquals(exists, findSearchViewTextField().exists());
     }
 
+    public void assertFragmentInputFocused(boolean focused)
+            throws UiObjectNotFoundException {
+        UiObject textField = findFragmentSearchViewTextField();
+
+        assertTrue(textField.exists());
+        assertEquals(focused, textField.isFocused());
+    }
+
+    public void assertFragmentInputExists(boolean exists)
+            throws UiObjectNotFoundException {
+        assertEquals(exists, findFragmentSearchViewTextField().exists());
+    }
+
     private UiObject findSearchView() {
-        return findObject("com.android.documentsui:id/option_menu_search");
+        return findObject(mTargetPackage + ":id/option_menu_search");
     }
 
     private UiObject findSearchViewTextField() {
-        return findObject("com.android.documentsui:id/option_menu_search", "android:id/search_src_text");
+        return findObject(mTargetPackage + ":id/option_menu_search",
+                mTargetPackage + ":id/search_src_text");
+    }
+
+    private UiObject findSearchViewClearButton() {
+        return findObject(mTargetPackage + ":id/option_menu_search",
+                mTargetPackage + ":id/search_close_btn");
+    }
+
+    private UiObject findFragmentSearchView() {
+        return findObject(mTargetPackage + ":id/search_view");
+    }
+
+    private UiObject findFragmentSearchViewTextField() {
+        return findObject(mTargetPackage + ":id/search_view",
+                mTargetPackage + ":id/search_src_text");
+    }
+
+    private UiObject findFragmentSearchClearButton() {
+        return findObject(mTargetPackage + ":id/search_view",
+                mTargetPackage + ":id/search_close_btn");
     }
 
     private UiObject findSearchViewIcon() {
         return mContext.getResources().getBoolean(R.bool.full_bar_search_view)
-                ? findObject("com.android.documentsui:id/option_menu_search")
-                : findObject("com.android.documentsui:id/option_menu_search", "android:id/search_button");
+                ? findObject(mTargetPackage + ":id/option_menu_search")
+                : findObject(mTargetPackage + ":id/option_menu_search",
+                        "android:id/search_button");
     }
 }
diff --git a/tests/common/com/android/documentsui/bots/SidebarBot.java b/tests/common/com/android/documentsui/bots/SidebarBot.java
index 9d95a93..4e96126 100644
--- a/tests/common/com/android/documentsui/bots/SidebarBot.java
+++ b/tests/common/com/android/documentsui/bots/SidebarBot.java
@@ -16,10 +16,10 @@
 
 package com.android.documentsui.bots;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.swipeLeft;
-import static android.support.test.espresso.action.ViewActions.swipeRight;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.swipeLeft;
+import static androidx.test.espresso.action.ViewActions.swipeRight;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
 
 import android.content.Context;
 import android.support.test.uiautomator.UiDevice;
@@ -43,11 +43,13 @@
  * the roots list drawer.
  */
 public class SidebarBot extends Bots.BaseBot {
-    private static final String ROOTS_LIST_ID = "com.android.documentsui:id/roots_list";
     private static final String TAG = "RootsListBot";
 
+    private final String mRootListId;
+
     public SidebarBot(UiDevice device, Context context, int timeout) {
         super(device, context, timeout);
+        mRootListId = mTargetPackage + ":id/roots_list";
     }
 
     private UiObject findRoot(String label) throws UiObjectNotFoundException {
@@ -55,8 +57,8 @@
         openDrawer();
 
         final UiSelector rootsList = new UiSelector().resourceId(
-                "com.android.documentsui:id/container_roots").childSelector(
-                new UiSelector().resourceId(ROOTS_LIST_ID));
+                mTargetPackage + ":id/container_roots").childSelector(
+                new UiSelector().resourceId(mRootListId));
 
         // Wait for the first list item to appear
         new UiObject(rootsList.childSelector(new UiSelector())).waitForExists(mTimeout);
@@ -74,14 +76,14 @@
 
     public void openDrawer() throws UiObjectNotFoundException {
         final UiSelector rootsList = new UiSelector().resourceId(
-                "com.android.documentsui:id/container_roots").childSelector(
-                new UiSelector().resourceId(ROOTS_LIST_ID));
+                mTargetPackage + ":id/container_roots").childSelector(
+                new UiSelector().resourceId(mRootListId));
 
         // We might need to expand drawer if not visible
         if (!new UiObject(rootsList).waitForExists(mTimeout)) {
             Log.d(TAG, "Failed to find roots list; trying to expand");
             final UiSelector hamburger = new UiSelector().resourceId(
-                    "com.android.documentsui:id/toolbar").childSelector(
+                    mTargetPackage + ":id/toolbar").childSelector(
                     new UiSelector().className("android.widget.ImageButton").clickable(true));
             new UiObject(hamburger).click();
         }
@@ -130,6 +132,6 @@
     }
 
     public void assertHasFocus() {
-        assertHasFocus(ROOTS_LIST_ID);
+        assertHasFocus(mRootListId);
     }
 }
diff --git a/tests/common/com/android/documentsui/bots/SortBot.java b/tests/common/com/android/documentsui/bots/SortBot.java
new file mode 100644
index 0000000..6b6f817
--- /dev/null
+++ b/tests/common/com/android/documentsui/bots/SortBot.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 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.documentsui.bots;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
+import static androidx.test.espresso.matcher.ViewMatchers.withChild;
+import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withParent;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.android.documentsui.sorting.SortDimension.SORT_DIRECTION_ASCENDING;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.hamcrest.Matchers.allOf;
+
+import android.content.Context;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.view.View;
+
+import androidx.annotation.StringRes;
+
+import com.android.documentsui.R;
+import com.android.documentsui.sorting.SortDimension;
+import com.android.documentsui.sorting.SortDimension.SortDirection;
+import com.android.documentsui.sorting.SortListFragment;
+import com.android.documentsui.sorting.SortModel;
+import com.android.documentsui.sorting.SortModel.SortDimensionId;
+
+import org.hamcrest.Matcher;
+
+/**
+ * A test helper class that provides support for controlling the UI Breadcrumb
+ * programmatically, and making assertions against the state of the UI.
+ * <p>
+ * Support for working directly with Roots and Directory view can be found in the respective bots.
+ */
+public class SortBot extends Bots.BaseBot {
+
+    private final SortModel mSortModel = SortModel.createModel();
+    private final ColumnSortBot mColumnBot;
+    private final UiBot mUiBot;
+
+    public SortBot(UiDevice device, Context context, int timeout, UiBot uiBot) {
+        super(device, context, timeout);
+        mColumnBot = new ColumnSortBot();
+        mUiBot = uiBot;
+    }
+
+    public void sortBy(@SortDimensionId int id, @SortDirection int direction) {
+        assert(direction != SortDimension.SORT_DIRECTION_NONE);
+
+        final @StringRes int labelId = mSortModel.getDimensionById(id).getLabelId();
+        final String label = mContext.getString(labelId);
+        final boolean result;
+        if (isHeaderShow()) {
+            result = mColumnBot.sortBy(label, direction);
+        } else {
+            result = sortByMenu(id, direction);
+        }
+
+        assertTrue("Sorting by id: " + id + " in direction: " + direction + " failed.",
+                result);
+    }
+
+    public boolean isHeaderShow() {
+        return Matchers.present(mColumnBot.MATCHER);
+    }
+
+    public void assertHeaderHide() {
+        assertFalse(Matchers.present(mColumnBot.MATCHER));
+    }
+
+    public void assertHeaderShow() {
+        // BEWARE THOSE WHO TREAD IN THIS DARK CORNER.
+        // Note that for some reason this doesn't work:
+        // assertTrue(Matchers.present(mColumnBot.MATCHER));
+        // Dunno why, something to do with our implementation
+        // or with espresso. It's sad that I'm leaving you
+        // with this little gremlin, but we all have to
+        // move on and get stuff done :)
+        assertTrue(Matchers.present(mColumnBot.MATCHER));
+    }
+
+    private boolean sortByMenu(@SortDimensionId int id, @SortDirection int direction) {
+        assert(direction != SortDimension.SORT_DIRECTION_NONE);
+
+        clickMenuSort();
+        mDevice.waitForIdle();
+
+        SortDimension dimension = mSortModel.getDimensionById(id);
+        @StringRes int labelRes = SortListFragment.getSheetLabelId(dimension, direction);
+        onView(withText(mContext.getString(labelRes))).perform(click());
+        mDevice.waitForIdle();
+
+        clickMenuSort();
+        mDevice.waitForIdle();
+
+        UiObject2 verifyLabel = mDevice.findObject(By.text(mContext.getString(labelRes)));
+        boolean isSelected = verifyLabel.isChecked();
+        onView(withText(mContext.getString(labelRes))).perform(click());
+
+        return isSelected;
+    }
+
+    private void clickMenuSort() {
+        mUiBot.clickToolbarOverflowItem(mContext.getString(R.string.menu_sort));
+    }
+
+    private static class ColumnSortBot {
+
+        private static final Matcher<View> MATCHER = withId(R.id.table_header);
+
+        private boolean sortBy(String label, @SortDirection int direction) {
+            final Matcher<View> cellMatcher = allOf(
+                    withChild(withText(label)),
+                    isDescendantOfA(MATCHER));
+            onView(cellMatcher).perform(click());
+
+            final @SortDirection int viewDirection = getDirection(cellMatcher);
+
+            if (viewDirection != direction) {
+                onView(cellMatcher).perform(click());
+            }
+
+            return getDirection(cellMatcher) == direction;
+        }
+
+        private @SortDirection int getDirection(Matcher<View> cellMatcher) {
+            final boolean ascending =
+                    Matchers.present(
+                            allOf(
+                                    withContentDescription(R.string.sort_direction_ascending),
+                                    withParent(cellMatcher)));
+            if (ascending) {
+                return SORT_DIRECTION_ASCENDING;
+            }
+
+            final boolean descending =
+                    Matchers.present(
+                            allOf(
+                                    withContentDescription(R.string.sort_direction_descending),
+                                    withParent(cellMatcher)));
+
+            return descending
+                    ? SortDimension.SORT_DIRECTION_DESCENDING
+                    : SortDimension.SORT_DIRECTION_NONE;
+        }
+    }
+}
diff --git a/tests/common/com/android/documentsui/bots/SortHeaderBot.java b/tests/common/com/android/documentsui/bots/SortHeaderBot.java
deleted file mode 100644
index ff6a839..0000000
--- a/tests/common/com/android/documentsui/bots/SortHeaderBot.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.bots;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
-import static android.support.test.espresso.matcher.ViewMatchers.withChild;
-import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withParent;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
-import static com.android.documentsui.sorting.SortDimension.SORT_DIRECTION_ASCENDING;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static org.hamcrest.Matchers.allOf;
-
-import android.app.UiAutomation;
-import android.content.Context;
-import android.support.annotation.StringRes;
-import android.support.test.uiautomator.UiDevice;
-import android.view.View;
-
-import com.android.documentsui.R;
-import com.android.documentsui.sorting.SortDimension;
-import com.android.documentsui.sorting.SortDimension.SortDirection;
-import com.android.documentsui.sorting.SortModel;
-import com.android.documentsui.sorting.SortModel.SortDimensionId;
-
-import org.hamcrest.Matcher;
-
-/**
- * A test helper class that provides support for controlling the UI Breadcrumb
- * programmatically, and making assertions against the state of the UI.
- * <p>
- * Support for working directly with Roots and Directory view can be found in the respective bots.
- */
-public class SortHeaderBot extends Bots.BaseBot {
-
-    private final SortModel mSortModel = SortModel.createModel();
-    private final DropdownSortBot mDropBot;
-    private final ColumnSortBot mColumnBot;
-
-    public SortHeaderBot(UiDevice device, Context context, int timeout) {
-        super(device, context, timeout);
-        mDropBot = new DropdownSortBot();
-        mColumnBot = new ColumnSortBot();
-    }
-
-    public void sortBy(@SortDimensionId int id, @SortDirection int direction) {
-        assert(direction != SortDimension.SORT_DIRECTION_NONE);
-
-        final @StringRes int labelId = mSortModel.getDimensionById(id).getLabelId();
-        final String label = mContext.getString(labelId);
-        final boolean result;
-        if (Matchers.present(mDropBot.MATCHER)) {
-            result = mDropBot.sortBy(label, direction);
-        } else {
-            result = mColumnBot.sortBy(label, direction);
-        }
-
-        assertTrue("Sorting by id: " + id + " in direction: " + direction + " failed.",
-                result);
-    }
-
-    public void assertDropdownMode() {
-        assertTrue(Matchers.present(mDropBot.MATCHER));
-    }
-
-    public void assertColumnMode() {
-        // BEWARE THOSE WHO TREAD IN THIS DARK CORNER.
-        // Note that for some reason this doesn't work:
-        // assertTrue(Matchers.present(mColumnBot.MATCHER));
-        // Dunno why, something to do with our implementation
-        // or with espresso. It's sad that I'm leaving you
-        // with this little gremlin, but we all have to
-        // move on and get stuff done :)
-        assertFalse(Matchers.present(mDropBot.MATCHER));
-    }
-
-    private static class DropdownSortBot {
-
-        private static final Matcher<View> MATCHER = withId(R.id.dropdown_sort_widget);
-        private static final Matcher<View> DROPDOWN_MATCHER = allOf(
-                withId(R.id.sort_dimen_dropdown),
-                withParent(MATCHER));
-        private static final Matcher<View> SORT_ARROW_MATCHER = allOf(
-                withId(R.id.sort_arrow),
-                withParent(MATCHER));
-
-        private boolean sortBy(String label, @SortDirection int direction) {
-            onView(DROPDOWN_MATCHER).perform(click());
-            onView(withText(label)).perform(click());
-
-            if (direction != getDirection()) {
-                onView(SORT_ARROW_MATCHER).perform(click());
-            }
-
-            return Matchers.present(allOf(
-                    DROPDOWN_MATCHER,
-                    withText(label)))
-                    && getDirection() == direction;
-        }
-
-        private @SortDirection int getDirection() {
-            final boolean ascending = Matchers.present(
-                    allOf(
-                            SORT_ARROW_MATCHER,
-                            withContentDescription(R.string.sort_direction_ascending)));
-
-            if (ascending) {
-                return SORT_DIRECTION_ASCENDING;
-            }
-
-            final boolean descending = Matchers.present(
-                    allOf(
-                            SORT_ARROW_MATCHER,
-                            withContentDescription(R.string.sort_direction_descending)));
-
-            return descending
-                    ? SortDimension.SORT_DIRECTION_DESCENDING
-                    : SortDimension.SORT_DIRECTION_NONE;
-        }
-    }
-
-    private static class ColumnSortBot {
-
-        private static final Matcher<View> MATCHER = withId(R.id.table_header);
-
-        private boolean sortBy(String label, @SortDirection int direction) {
-            final Matcher<View> cellMatcher = allOf(
-                    withChild(withText(label)),
-                    isDescendantOfA(MATCHER));
-            onView(cellMatcher).perform(click());
-
-            final @SortDirection int viewDirection = getDirection(cellMatcher);
-
-            if (viewDirection != direction) {
-                onView(cellMatcher).perform(click());
-            }
-
-            return getDirection(cellMatcher) == direction;
-        }
-
-        private @SortDirection int getDirection(Matcher<View> cellMatcher) {
-            final boolean ascending =
-                    Matchers.present(
-                            allOf(
-                                    withContentDescription(R.string.sort_direction_ascending),
-                                    withParent(cellMatcher)));
-            if (ascending) {
-                return SORT_DIRECTION_ASCENDING;
-            }
-
-            final boolean descending =
-                    Matchers.present(
-                            allOf(
-                                    withContentDescription(R.string.sort_direction_descending),
-                                    withParent(cellMatcher)));
-
-            return descending
-                    ? SortDimension.SORT_DIRECTION_DESCENDING
-                    : SortDimension.SORT_DIRECTION_NONE;
-        }
-    }
-}
diff --git a/tests/common/com/android/documentsui/bots/UiBot.java b/tests/common/com/android/documentsui/bots/UiBot.java
index 3552418..0043bf7 100644
--- a/tests/common/com/android/documentsui/bots/UiBot.java
+++ b/tests/common/com/android/documentsui/bots/UiBot.java
@@ -16,25 +16,24 @@
 
 package com.android.documentsui.bots;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.hasFocus;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.hasFocus;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
 import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.Matchers.endsWith;
 
 import android.content.Context;
-import android.support.test.espresso.Espresso;
-import android.support.test.espresso.action.ViewActions;
-import android.support.test.espresso.matcher.BoundedMatcher;
-import android.support.test.espresso.matcher.ViewMatchers;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
@@ -44,7 +43,13 @@
 import android.support.test.uiautomator.Until;
 import android.util.TypedValue;
 import android.view.View;
-import android.widget.Toolbar;
+
+import androidx.appcompat.widget.Toolbar;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.espresso.Espresso;
+import androidx.test.espresso.action.ViewActions;
+import androidx.test.espresso.matcher.BoundedMatcher;
+import androidx.test.espresso.matcher.ViewMatchers;
 
 import com.android.documentsui.R;
 
@@ -62,7 +67,7 @@
  */
 public class UiBot extends Bots.BaseBot {
 
-    public static final String TARGET_PKG = "com.android.documentsui";
+    public static String targetPackageName;
 
     @SuppressWarnings("unchecked")
     private static final Matcher<View> TOOLBAR = allOf(
@@ -89,6 +94,8 @@
 
     public UiBot(UiDevice device, Context context, int timeout) {
         super(device, context, timeout);
+        targetPackageName =
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName();
     }
 
     public void assertWindowTitle(String expected) {
@@ -96,6 +103,12 @@
                 .check(matches(withToolbarTitle(is(expected))));
     }
 
+    public void assertSearchBarShow() {
+        UiSelector selector = new UiSelector().text(mContext.getString(R.string.search_bar_hint));
+        UiObject searchHint = mDevice.findObject(selector);
+        assertTrue(searchHint.exists());
+    }
+
     public void assertMenuEnabled(int id, boolean enabled) {
         UiObject2 menu = findMenuWithName(mContext.getString(id));
         assertNotNull(menu);
@@ -193,10 +206,27 @@
 
     public boolean waitForActionModeBarToAppear() {
         UiObject2 bar =
-                mDevice.wait(Until.findObject(By.res("android:id/action_mode_bar")), mTimeout);
+                mDevice.wait(Until.findObject(
+                        By.res(mTargetPackage + ":id/action_mode_bar")), mTimeout);
         return (bar != null);
     }
 
+    public void clickRename() throws UiObjectNotFoundException {
+        if (!waitForActionModeBarToAppear()) {
+            throw new UiObjectNotFoundException("ActionMode bar not found");
+        }
+        clickActionbarOverflowItem(mContext.getString(R.string.menu_rename));
+        mDevice.waitForIdle();
+    }
+
+    public void clickDelete() throws UiObjectNotFoundException {
+        if (!waitForActionModeBarToAppear()) {
+            throw new UiObjectNotFoundException("ActionMode bar not found");
+        }
+        clickToolbarItem(R.id.action_menu_delete);
+        mDevice.waitForIdle();
+    }
+
     public UiObject findDownloadRetryDialog() {
         UiSelector selector = new UiSelector().text("Couldn't download");
         UiObject title = mDevice.findObject(selector);
@@ -262,7 +292,7 @@
     }
 
     UiObject findMenuMoreOptions() {
-        UiSelector selector = new UiSelector().className("android.widget.ImageButton")
+        UiSelector selector = new UiSelector().className("android.widget.ImageView")
                 .descriptionContains("More options");
         // TODO: use the system string ? android.R.string.action_menu_overflow_description
         return mDevice.findObject(selector);
diff --git a/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java b/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java
index e2160cf..c7ccaf9 100644
--- a/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java
+++ b/tests/common/com/android/documentsui/dirlist/TestDocumentsAdapter.java
@@ -18,13 +18,13 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.AdapterDataObserver;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
 import android.view.ViewGroup;
 
 import com.android.documentsui.Model.Update;
 import com.android.documentsui.base.EventListener;
-import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.testing.TestEventListener;
 
 import java.util.ArrayList;
@@ -51,7 +51,7 @@
 
             @Override
             public void onItemRangeChanged(int startPosition, int itemCount, Object payload) {
-                if (SelectionHelper.SELECTION_CHANGED_MARKER.equals(payload)) {
+                if (SelectionTracker.SELECTION_CHANGED_MARKER.equals(payload)) {
                     int last = startPosition + itemCount;
                     for (int i = startPosition; i < last; i++) {
                         mSelectionChanged.add(i);
diff --git a/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java b/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java
index 8dfbdea..5656655 100644
--- a/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java
+++ b/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java
@@ -59,7 +59,7 @@
     }
 
     @Override
-    public int getFocusPosition() {
+    public int getFocusedPosition() {
         return focusPos;
     }
 
diff --git a/tests/common/com/android/documentsui/filters/HugeLongTest.java b/tests/common/com/android/documentsui/filters/HugeLongTest.java
new file mode 100644
index 0000000..ef5ee6e
--- /dev/null
+++ b/tests/common/com/android/documentsui/filters/HugeLongTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 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.
+ *
+ */
+
+/*
+ * Copyright (C) 2019 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.documentsui.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test that should run as part of the Huge and take a long time tests.
+ *
+ * Please mark the test whose duration is larger than 10 seconds.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface HugeLongTest {
+}
diff --git a/tests/common/com/android/documentsui/services/TestCopyJobProcessTracker.java b/tests/common/com/android/documentsui/services/TestCopyJobProcessTracker.java
new file mode 100644
index 0000000..e0e9d3f
--- /dev/null
+++ b/tests/common/com/android/documentsui/services/TestCopyJobProcessTracker.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 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.documentsui.services;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Notification;
+
+import com.android.documentsui.services.CopyJob.CopyJobProgressTracker;
+
+import java.util.function.Function;
+import java.util.function.LongSupplier;
+
+class TestCopyJobProcessTracker<T extends CopyJobProgressTracker> {
+    private T mProcessTracker;
+    private Notification.Builder mProgressBuilder;
+    private final Function<Double, String> mProgressFormatter;
+    private final Function<Long, String> mRemainTimeFormatter;
+
+    private static class TestLongSupplier implements LongSupplier {
+        long mValue = 0;
+        boolean mCalled;
+
+        @Override
+        public long getAsLong() {
+            mCalled = true;
+            return mValue;
+        }
+    }
+    private TestLongSupplier mTimeSupplier = new TestLongSupplier();
+
+    TestCopyJobProcessTracker(Class<T> trackerClass,
+            long requiredData, CopyJob job, Function<Double, String> progressFormatter,
+            Function<Long, String> remainTimeFormatter) throws Exception {
+
+        mProcessTracker = trackerClass.getDeclaredConstructor(long.class,
+                LongSupplier.class).newInstance(requiredData, mTimeSupplier);
+
+        mProgressBuilder = job.mProgressBuilder;
+        mProgressFormatter = progressFormatter;
+        mRemainTimeFormatter = remainTimeFormatter;
+    }
+
+    T getProcessTracker() {
+        return mProcessTracker;
+    }
+
+    void assertProgressTrackStarted() {
+        assertTrue(mTimeSupplier.mCalled);
+    }
+
+    void assertStartedProgressEquals(int expectedProgress) {
+        assertEquals(expectedProgress, (int) mProcessTracker.getProgress());
+    }
+
+    void assertStartedRemainingTimeEquals(long expectedRemainingTime) {
+        assertEquals(expectedRemainingTime, mProcessTracker.getRemainingTimeEstimate());
+    }
+
+    void updateProgressAndRemainingTime(long elapsedTime) {
+        mTimeSupplier.mValue = elapsedTime;
+        mProcessTracker.update(mProgressBuilder, mRemainTimeFormatter);
+    }
+
+    void assertProgressEquals(double progress) {
+        assertEquals(mProgressFormatter.apply(progress),
+                mProgressBuilder.build().extras.get(Notification.EXTRA_SUB_TEXT));
+    }
+
+    void assertReminingTimeEquals(long remainingTime) {
+        assertEquals(mRemainTimeFormatter.apply(remainingTime),
+                mProgressBuilder.build().extras.get(Notification.EXTRA_TEXT));
+    }
+
+    void assertNoRemainingTime() {
+        assertNull(mProgressBuilder.build().extras.get(Notification.EXTRA_TEXT));
+    }
+}
diff --git a/tests/common/com/android/documentsui/services/TestJobListener.java b/tests/common/com/android/documentsui/services/TestJobListener.java
index 6977806..e028585 100644
--- a/tests/common/com/android/documentsui/services/TestJobListener.java
+++ b/tests/common/com/android/documentsui/services/TestJobListener.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.fail;
 
 import android.net.Uri;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
 
 import com.android.documentsui.base.DocumentInfo;
 
diff --git a/tests/common/com/android/documentsui/services/TestNotificationService.java b/tests/common/com/android/documentsui/services/TestNotificationService.java
index 65af9a0..b1e5c21 100644
--- a/tests/common/com/android/documentsui/services/TestNotificationService.java
+++ b/tests/common/com/android/documentsui/services/TestNotificationService.java
@@ -17,19 +17,21 @@
 
 import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
+import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.ProgressBar;
 import android.widget.RemoteViews;
-import android.util.Log;
 
 /**
 * This class receives a callback when Notification is posted or removed
@@ -58,13 +60,13 @@
     public static final String EXTRA_ERROR_REASON =
             "com.android.documentsui.services.TestNotificationService.EXTRA_ERROR_REASON";
 
-    private final static String DOCUMENTSUI_PACKAGE= "com.android.documentsui";
-
     public enum MODE {
         CANCEL_MODE,
         EXECUTION_MODE;
     }
 
+    private static String mTargetPackageName;
+
     private MODE mCurrentMode = MODE.CANCEL_MODE;
 
     private boolean mCancelled = false;
@@ -87,6 +89,7 @@
 
     @Override
     public void onCreate() {
+        mTargetPackageName = getTargetPackageName();
         mFrameLayout = new FrameLayout(getBaseContext());
         IntentFilter filter = new IntentFilter();
         filter.addAction(ACTION_CHANGE_CANCEL_MODE);
@@ -110,7 +113,7 @@
     @Override
     public void onNotificationPosted(StatusBarNotification sbn) {
         String pkgName = sbn.getPackageName();
-        if (DOCUMENTSUI_PACKAGE.equals(pkgName)) {
+        if (mTargetPackageName.equals(pkgName)) {
             if (MODE.CANCEL_MODE.equals(mCurrentMode)) {
                 try {
                     mCancelled = doCancel(sbn.getNotification());
@@ -124,7 +127,7 @@
     @Override
     public void onNotificationRemoved(StatusBarNotification sbn) {
         String pkgName = sbn.getPackageName();
-        if (!DOCUMENTSUI_PACKAGE.equals(pkgName)) {
+        if (!mTargetPackageName.equals(pkgName)) {
             return;
         }
 
@@ -220,4 +223,14 @@
         }
         return result;
     }
+
+    private String getTargetPackageName() {
+        final PackageManager pm = getPackageManager();
+
+        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+        intent.addCategory(Intent.CATEGORY_OPENABLE);
+        intent.setType("*/*");
+        final ResolveInfo ri = pm.resolveActivity(intent, 0);
+        return ri.activityInfo.packageName;
+    }
 }
diff --git a/tests/common/com/android/documentsui/testing/LatchedConsumer.java b/tests/common/com/android/documentsui/testing/LatchedConsumer.java
new file mode 100644
index 0000000..6545efe
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/LatchedConsumer.java
@@ -0,0 +1,41 @@
+package com.android.documentsui.testing;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Helper class for testing async processes.
+ */
+public class LatchedConsumer<T> implements Consumer<T> {
+
+    private T value;
+    private CountDownLatch latch;
+
+    public LatchedConsumer(int expectedCount) {
+        latch = new CountDownLatch(expectedCount);
+    }
+
+    public CountDownLatch getLatch() { return latch; }
+    public T getValue() { return value; }
+
+
+    @Override
+    public void accept(T value) {
+        this.value = value;
+        latch.countDown();
+    }
+
+    public void assertNotCalled(long timeout, TimeUnit unit)
+            throws InterruptedException {
+        assertFalse(latch.await(timeout, unit));
+    }
+
+    public void assertCalled(long timeout, TimeUnit unit)
+            throws InterruptedException {
+        assertTrue(latch.await(timeout, unit));
+    }
+}
diff --git a/tests/common/com/android/documentsui/testing/SelectionHelpers.java b/tests/common/com/android/documentsui/testing/SelectionHelpers.java
deleted file mode 100644
index 70bc44d..0000000
--- a/tests/common/com/android/documentsui/testing/SelectionHelpers.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.testing;
-
-import com.android.documentsui.DocsSelectionHelper;
-import com.android.documentsui.dirlist.DocsStableIdProvider;
-import com.android.documentsui.dirlist.DocumentsAdapter;
-import com.android.documentsui.dirlist.TestDocumentsAdapter;
-import com.android.documentsui.selection.DefaultSelectionHelper;
-import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-
-import java.util.Collections;
-import java.util.List;
-
-public class SelectionHelpers {
-
-    public static final SelectionPredicate CAN_SET_ANYTHING = new SelectionPredicate() {
-        @Override
-        public boolean canSetStateForId(String id, boolean nextState) {
-            return true;
-        }
-
-        @Override
-        public boolean canSetStateAtPosition(int position, boolean nextState) {
-            return true;
-        }
-    };
-
-    private SelectionHelpers() {}
-
-    public static DocsSelectionHelper createTestInstance() {
-        return createTestInstance(Collections.emptyList());
-    }
-
-    public static DocsSelectionHelper createTestInstance(List<String> docs) {
-        return createTestInstance(docs, DefaultSelectionHelper.MODE_MULTIPLE);
-    }
-
-    public static DocsSelectionHelper createTestInstance(
-            List<String> docs, @SelectionMode int mode) {
-        return createTestInstance(new TestDocumentsAdapter(docs), mode, CAN_SET_ANYTHING);
-    }
-
-    public static DocsSelectionHelper createTestInstance(
-            DocumentsAdapter adapter, @SelectionMode int mode, SelectionPredicate canSetState) {
-        DocsSelectionHelper manager = mode == DefaultSelectionHelper.MODE_SINGLE
-                ? DocsSelectionHelper.createSingleSelect()
-                : DocsSelectionHelper.createMultiSelect();
-
-        manager.reset(adapter, new DocsStableIdProvider(adapter), canSetState);
-
-        return manager;
-    }
-}
diff --git a/tests/common/com/android/documentsui/testing/TestActionHandler.java b/tests/common/com/android/documentsui/testing/TestActionHandler.java
index cd3fb1a..7b11d41 100644
--- a/tests/common/com/android/documentsui/testing/TestActionHandler.java
+++ b/tests/common/com/android/documentsui/testing/TestActionHandler.java
@@ -18,11 +18,12 @@
 
 import android.content.Intent;
 
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+
 import com.android.documentsui.AbstractActionHandler;
 import com.android.documentsui.TestActivity;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 import java.util.function.Consumer;
 
@@ -30,7 +31,7 @@
 
     private final TestEnv mEnv;
 
-    public final TestEventHandler<ItemDetails> open = new TestEventHandler<>();
+    public final TestEventHandler<ItemDetails<String>> open = new TestEventHandler<>();
     public boolean mDeleteHappened;
 
     public DocumentInfo nextRootDocument;
@@ -53,7 +54,7 @@
     }
 
     @Override
-    public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
+    public boolean openItem(ItemDetails<String> doc, @ViewType int type, @ViewType int fallback) {
         return open.accept(doc);
     }
 
diff --git a/tests/common/com/android/documentsui/testing/TestDocumentClipper.java b/tests/common/com/android/documentsui/testing/TestDocumentClipper.java
index 3d6c9ad..9fa4f2e 100644
--- a/tests/common/com/android/documentsui/testing/TestDocumentClipper.java
+++ b/tests/common/com/android/documentsui/testing/TestDocumentClipper.java
@@ -20,10 +20,11 @@
 import android.net.Uri;
 import android.util.Pair;
 
+import androidx.recyclerview.selection.Selection;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.clipping.DocumentClipper;
-import com.android.documentsui.selection.Selection;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.services.FileOperations.Callback;
@@ -49,8 +50,8 @@
     }
 
     @Override
-    public ClipData getClipDataForDocuments(Function<String, Uri> uriBuilder, Selection selection,
-            int opType) {
+    public ClipData getClipDataForDocuments(
+            Function<String, Uri> uriBuilder, Selection<String> selection, int opType) {
         return nextClip;
     }
 
@@ -67,11 +68,11 @@
     }
 
     @Override
-    public void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection selection) {
+    public void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection<String> selection) {
     }
 
     @Override
-    public void clipDocumentsForCut(Function<String, Uri> uriBuilder, Selection selection,
+    public void clipDocumentsForCut(Function<String, Uri> uriBuilder, Selection<String> selection,
             DocumentInfo parent) {
         List<Uri> uris = new ArrayList<>(selection.size());
         for (String id : selection) {
diff --git a/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java b/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java
index 9f30326..794d1c9 100644
--- a/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java
+++ b/tests/common/com/android/documentsui/testing/TestDocumentsProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.documentsui.testing;
 
+import android.annotation.NonNull;
 import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.database.MatrixCursor;
@@ -90,6 +91,15 @@
     }
 
     @Override
+    public Cursor querySearchDocuments(String rootId, String query, String[] projection) {
+        if (mNextChildDocuments != null) {
+            return filterCursorByString(mNextChildDocuments, query);
+        }
+
+        return mNextChildDocuments;
+    }
+
+    @Override
     public boolean onCreate() {
         return true;
     }
@@ -122,4 +132,39 @@
 
         return cursor;
     }
+
+    private static Cursor filterCursorByString(@NonNull Cursor cursor, String query) {
+        final int count = cursor.getCount();
+        final String[] columnNames = cursor.getColumnNames();
+
+        final MatrixCursor resultCursor = new MatrixCursor(columnNames, count);
+        cursor.moveToPosition(-1);
+        for (int i = 0; i < count; i++) {
+            cursor.moveToNext();
+            final int index = cursor.getColumnIndex(Document.COLUMN_DISPLAY_NAME);
+            if (!cursor.getString(index).contains(query)) {
+                continue;
+            }
+
+            final MatrixCursor.RowBuilder builder = resultCursor.newRow();
+            final int columnCount = cursor.getColumnCount();
+            for (int j = 0; j < columnCount; j++) {
+                final int type = cursor.getType(j);
+                switch (type) {
+                    case Cursor.FIELD_TYPE_INTEGER:
+                        builder.add(cursor.getLong(j));
+                        break;
+
+                    case Cursor.FIELD_TYPE_STRING:
+                        builder.add(cursor.getString(j));
+                        break;
+
+                    default:
+                        break;
+                }
+            }
+        }
+        cursor.moveToPosition(-1);
+        return resultCursor;
+    }
 }
diff --git a/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java b/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java
index ddd5c13..95f4165 100644
--- a/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java
+++ b/tests/common/com/android/documentsui/testing/TestDragAndDropManager.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.testing;
 
-import android.annotation.Nullable;
+import androidx.annotation.Nullable;
 import android.content.ClipData;
 import android.net.Uri;
 import android.util.Pair;
diff --git a/tests/common/com/android/documentsui/testing/TestDrawerController.java b/tests/common/com/android/documentsui/testing/TestDrawerController.java
new file mode 100644
index 0000000..d1e486c
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestDrawerController.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 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.documentsui.testing;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.android.documentsui.DrawerController;
+
+import org.mockito.Mockito;
+
+/**
+ * We use abstract so we don't have to implement all the necessary methods from the interface.
+ * To get an instance, use {@link #create()}.
+ */
+public abstract class TestDrawerController extends DrawerController {
+
+    public static TestDrawerController create() {
+        TestDrawerController drawController = Mockito.mock(
+                TestDrawerController.class);
+        Mockito.doCallRealMethod().when(drawController).openDrawer(Mockito.anyBoolean());
+        Mockito.doCallRealMethod().when(drawController).assertWasOpened();
+        Mockito.doCallRealMethod().when(drawController).assertWasClosed();
+
+        return drawController;
+    }
+
+    public void openDrawer(boolean open) {
+        when(isPresent()).thenReturn(open);
+        when(isOpen()).thenReturn(open);
+    }
+
+    public void assertWasOpened() {
+        verify(this).setOpen(false);
+    }
+
+    public void assertWasClosed() {
+        verify(this, never()).setOpen(false);
+    }
+}
\ No newline at end of file
diff --git a/tests/common/com/android/documentsui/testing/TestEnv.java b/tests/common/com/android/documentsui/testing/TestEnv.java
index 40b5e0a..6ddd047 100644
--- a/tests/common/com/android/documentsui/testing/TestEnv.java
+++ b/tests/common/com/android/documentsui/testing/TestEnv.java
@@ -17,12 +17,15 @@
 
 import android.content.Context;
 import android.provider.DocumentsContract.Document;
-import android.support.test.InstrumentationRegistry;
 import android.test.mock.MockContentResolver;
 
+import androidx.test.InstrumentationRegistry;
+
 import com.android.documentsui.DocsSelectionHelper;
 import com.android.documentsui.FocusManager;
 import com.android.documentsui.Injector;
+import com.android.documentsui.ModelId;
+import com.android.documentsui.SelectionHelpers;
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Features;
@@ -171,7 +174,8 @@
     }
 
     public void populateStack() {
-        DocumentInfo rootDoc = model.getDocument("1");
+        DocumentInfo rootDoc = model.getDocument(
+                ModelId.build(TestProvidersAccess.HOME.authority, "1"));
 
         // These are test setup sanity checks, not test assertions.
         assert rootDoc != null;
@@ -192,7 +196,7 @@
 
     public void selectDocument(DocumentInfo info) {
         List<String> ids = new ArrayList<>(1);
-        ids.add(info.documentId);
+        ids.add(ModelId.build(info.authority, info.documentId));
         selectionMgr.setItemsSelected(ids, true);
     }
 
diff --git a/tests/common/com/android/documentsui/testing/TestEvents.java b/tests/common/com/android/documentsui/testing/TestEvents.java
index 9aab9e8..798120c 100644
--- a/tests/common/com/android/documentsui/testing/TestEvents.java
+++ b/tests/common/com/android/documentsui/testing/TestEvents.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.testing;
 
-import android.annotation.IntDef;
+import androidx.annotation.IntDef;
 import android.graphics.Point;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
diff --git a/tests/common/com/android/documentsui/testing/TestFeatures.java b/tests/common/com/android/documentsui/testing/TestFeatures.java
index 39f88a0..7f3bd9d 100644
--- a/tests/common/com/android/documentsui/testing/TestFeatures.java
+++ b/tests/common/com/android/documentsui/testing/TestFeatures.java
@@ -15,7 +15,7 @@
  */
 package com.android.documentsui.testing;
 
-import android.annotation.BoolRes;
+import androidx.annotation.BoolRes;
 
 import com.android.documentsui.base.Features;
 
@@ -36,6 +36,7 @@
     public boolean remoteActions = true;
     public boolean systemKeyboardNavigation = true;
     public boolean virtualFilesSharing = true;
+    public boolean forceDefaultRoot = false;
 
     @Override
     public boolean isArchiveCreationEnabled() {
@@ -113,6 +114,11 @@
     }
 
     @Override
+    public boolean isDefaultRootInBrowseEnabled() {
+        return forceDefaultRoot;
+    }
+
+    @Override
     public void forceFeature(@BoolRes int feature, boolean enabled) {
         throw new UnsupportedOperationException("Implement as needed.");
     }
diff --git a/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java b/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java
index f883e5e..fd4fe16 100644
--- a/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java
+++ b/tests/common/com/android/documentsui/testing/TestGridLayoutManager.java
@@ -17,7 +17,7 @@
 package com.android.documentsui.testing;
 
 import android.content.Context;
-import android.support.v7.widget.GridLayoutManager;
+import androidx.recyclerview.widget.GridLayoutManager;
 
 import org.mockito.Mockito;
 
diff --git a/tests/common/com/android/documentsui/testing/TestLoaderManager.java b/tests/common/com/android/documentsui/testing/TestLoaderManager.java
index 3344398..172b9f5 100644
--- a/tests/common/com/android/documentsui/testing/TestLoaderManager.java
+++ b/tests/common/com/android/documentsui/testing/TestLoaderManager.java
@@ -86,7 +86,6 @@
     public void runAsyncTaskLoader(int id) {
         AsyncTaskLoader loader = (AsyncTaskLoader) getLoader(id);
         loader.startLoading();
-        loader.waitForLoader();
     }
 
     @Override
diff --git a/tests/common/com/android/documentsui/testing/TestMenu.java b/tests/common/com/android/documentsui/testing/TestMenu.java
index 6a46668..61a7b4d 100644
--- a/tests/common/com/android/documentsui/testing/TestMenu.java
+++ b/tests/common/com/android/documentsui/testing/TestMenu.java
@@ -18,7 +18,8 @@
 
 import android.util.SparseArray;
 import android.view.Menu;
-import android.widget.SearchView;
+
+import androidx.appcompat.widget.SearchView;
 
 import com.android.documentsui.R;
 
@@ -56,10 +57,10 @@
                 R.id.root_menu_open_in_new_window,
                 R.id.root_menu_paste_into_folder,
                 R.id.root_menu_settings,
-                R.id.action_menu_open,
                 R.id.action_menu_open_with,
                 R.id.action_menu_share,
                 R.id.action_menu_delete,
+                R.id.action_menu_select,
                 R.id.action_menu_select_all,
                 R.id.action_menu_copy_to,
                 R.id.action_menu_extract_to,
@@ -68,16 +69,18 @@
                 R.id.action_menu_rename,
                 R.id.action_menu_inspect,
                 R.id.action_menu_view_in_owner,
+                R.id.action_menu_sort,
                 R.id.option_menu_search,
                 R.id.option_menu_debug,
-                R.id.option_menu_grid,
-                R.id.option_menu_list,
                 R.id.option_menu_new_window,
                 R.id.option_menu_create_dir,
                 R.id.option_menu_select_all,
                 R.id.option_menu_advanced,
                 R.id.option_menu_settings,
-                R.id.option_menu_inspect);
+                R.id.option_menu_inspect,
+                R.id.option_menu_sort,
+                R.id.sub_menu_grid,
+                R.id.sub_menu_list);
     }
 
 
diff --git a/tests/common/com/android/documentsui/testing/TestMenuInflater.java b/tests/common/com/android/documentsui/testing/TestMenuInflater.java
index 9b660a5..27a8aa4 100644
--- a/tests/common/com/android/documentsui/testing/TestMenuInflater.java
+++ b/tests/common/com/android/documentsui/testing/TestMenuInflater.java
@@ -16,11 +16,12 @@
 
 package com.android.documentsui.testing;
 
-import android.annotation.MenuRes;
-import android.support.test.InstrumentationRegistry;
 import android.view.Menu;
 import android.view.MenuInflater;
 
+import androidx.annotation.MenuRes;
+import androidx.test.InstrumentationRegistry;
+
 public class TestMenuInflater extends MenuInflater {
 
     public int lastInflatedMenuId;
diff --git a/tests/common/com/android/documentsui/testing/TestMenuItem.java b/tests/common/com/android/documentsui/testing/TestMenuItem.java
index 9f4df28..a0562db 100644
--- a/tests/common/com/android/documentsui/testing/TestMenuItem.java
+++ b/tests/common/com/android/documentsui/testing/TestMenuItem.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.annotation.StringRes;
+import androidx.annotation.StringRes;
 import android.view.MenuItem;
 import android.view.View;
 
diff --git a/tests/common/com/android/documentsui/testing/TestPackageManager.java b/tests/common/com/android/documentsui/testing/TestPackageManager.java
index e0b27a2..a923011 100644
--- a/tests/common/com/android/documentsui/testing/TestPackageManager.java
+++ b/tests/common/com/android/documentsui/testing/TestPackageManager.java
@@ -16,7 +16,6 @@
 
 package com.android.documentsui.testing;
 
-import android.annotation.UserIdInt;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -93,7 +92,7 @@
     }
 
     public final ResolveInfo resolveActivityAsUser(
-            Intent intent, int flags, @UserIdInt int userId) {
+            Intent intent, int flags, int userId) {
         return resolveActivity(intent, flags);
     }
 
diff --git a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java
index 248bb53..13c5c34 100644
--- a/tests/common/com/android/documentsui/testing/TestProvidersAccess.java
+++ b/tests/common/com/android/documentsui/testing/TestProvidersAccess.java
@@ -39,6 +39,11 @@
     public static final RootInfo PICKLES;
     public static final RootInfo RECENTS;
     public static final RootInfo INSPECTOR;
+    public static final RootInfo IMAGE;
+    public static final RootInfo AUDIO;
+    public static final RootInfo VIDEO;
+    public static final RootInfo EXTERNALSTORAGE;
+
 
     static {
         DOWNLOADS = new RootInfo() {{
@@ -47,6 +52,7 @@
         DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS;
         DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS;
         DOWNLOADS.title = "Downloads";
+        DOWNLOADS.derivedType = RootInfo.TYPE_DOWNLOADS;
         DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY
                 | Root.FLAG_SUPPORTS_CREATE
                 | Root.FLAG_SUPPORTS_IS_CHILD
@@ -56,6 +62,7 @@
         HOME.authority = Providers.AUTHORITY_STORAGE;
         HOME.rootId = Providers.ROOT_ID_HOME;
         HOME.title = "Home";
+        HOME.derivedType = RootInfo.TYPE_LOCAL;
         HOME.flags = Root.FLAG_LOCAL_ONLY
                 | Root.FLAG_SUPPORTS_CREATE
                 | Root.FLAG_SUPPORTS_IS_CHILD
@@ -65,6 +72,8 @@
         HAMMY.authority = "yummies";
         HAMMY.rootId = "hamsandwich";
         HAMMY.title = "Ham Sandwich";
+        HAMMY.derivedType = RootInfo.TYPE_LOCAL;
+        HAMMY.flags = Root.FLAG_LOCAL_ONLY;
 
         PICKLES = new RootInfo();
         PICKLES.authority = "yummies";
@@ -85,6 +94,30 @@
         INSPECTOR.title = "Inspector";
         INSPECTOR.flags = Root.FLAG_LOCAL_ONLY
             | Root.FLAG_SUPPORTS_CREATE;
+
+        IMAGE = new RootInfo();
+        IMAGE.authority = Providers.AUTHORITY_MEDIA;
+        IMAGE.rootId = Providers.ROOT_ID_IMAGES;
+        IMAGE.title = "Images";
+        IMAGE.derivedType = RootInfo.TYPE_IMAGES;
+
+        AUDIO = new RootInfo();
+        AUDIO.authority = Providers.AUTHORITY_MEDIA;
+        AUDIO.rootId = Providers.ROOT_ID_AUDIO;
+        AUDIO.title = "Audio";
+        AUDIO.derivedType = RootInfo.TYPE_AUDIO;
+
+        VIDEO = new RootInfo();
+        VIDEO.authority = Providers.AUTHORITY_MEDIA;
+        VIDEO.rootId = Providers.ROOT_ID_VIDEOS;
+        VIDEO.title = "Videos";
+        VIDEO.derivedType = RootInfo.TYPE_VIDEO;
+
+        EXTERNALSTORAGE = new RootInfo();
+        EXTERNALSTORAGE.authority = Providers.AUTHORITY_STORAGE;
+        EXTERNALSTORAGE.rootId = Providers.ROOT_ID_DEVICE;
+        EXTERNALSTORAGE.title = "Device";
+        EXTERNALSTORAGE.derivedType = RootInfo.TYPE_LOCAL;
     }
 
     public final Map<String, Collection<RootInfo>> roots = new HashMap<>();
diff --git a/tests/common/com/android/documentsui/testing/TestRecyclerView.java b/tests/common/com/android/documentsui/testing/TestRecyclerView.java
index a1f8e7f..3e14534 100644
--- a/tests/common/com/android/documentsui/testing/TestRecyclerView.java
+++ b/tests/common/com/android/documentsui/testing/TestRecyclerView.java
@@ -17,10 +17,11 @@
 package com.android.documentsui.testing;
 
 import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.v7.widget.RecyclerView;
 import android.view.View;
 
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.InstrumentationRegistry;
+
 import com.android.documentsui.dirlist.TestDocumentsAdapter;
 
 import org.mockito.Mockito;
@@ -28,10 +29,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 public class TestRecyclerView extends RecyclerView {
 
-    private List<RecyclerView.ViewHolder> holders = new ArrayList<>();
+    private List<RecyclerView.ViewHolder> mHolders = new ArrayList<>();
     private TestDocumentsAdapter adapter;
     private RecyclerView.LayoutManager mLayoutManager;
 
@@ -40,8 +40,17 @@
     }
 
     @Override
+    public ViewHolder getChildViewHolder(View child) {
+        return mHolders.get(0);
+    }
+
+    public void setHolders(List<ViewHolder> holders) {
+        mHolders = holders;
+    }
+
+    @Override
     public ViewHolder findViewHolderForAdapterPosition(int position) {
-        return holders.get(position);
+        return mHolders.get(position);
     }
 
     @Override
@@ -68,9 +77,9 @@
     }
 
     public void setItems(List<String> modelIds) {
-        holders = new ArrayList<>();
+        mHolders = new ArrayList<>();
         for (String modelId: modelIds) {
-            holders.add(new TestViewHolder(Views.createTestView()));
+            mHolders.add(new TestViewHolder(Views.createTestView()));
         }
         adapter.updateTestModelIds(modelIds);
     }
@@ -78,16 +87,16 @@
     public static TestRecyclerView create(List<String> modelIds) {
         final TestRecyclerView view =
                 new TestRecyclerView(InstrumentationRegistry.getTargetContext());
-        view.holders = new ArrayList<>();
+        view.mHolders = new ArrayList<>();
         for (String modelId: modelIds) {
-            view.holders.add(new TestViewHolder(Views.createTestView()));
+            view.mHolders.add(new TestViewHolder(Views.createTestView()));
         }
         view.adapter = new TestDocumentsAdapter(modelIds);
         return view;
     }
 
     public void assertItemViewFocused(int pos) {
-        Mockito.verify(holders.get(pos).itemView).requestFocus();
+        Mockito.verify(mHolders.get(pos).itemView).requestFocus();
     }
 
     private static class TestViewHolder extends RecyclerView.ViewHolder {
diff --git a/tests/common/com/android/documentsui/testing/TestResources.java b/tests/common/com/android/documentsui/testing/TestResources.java
index 0bd21de..2230581 100644
--- a/tests/common/com/android/documentsui/testing/TestResources.java
+++ b/tests/common/com/android/documentsui/testing/TestResources.java
@@ -16,10 +16,10 @@
 
 package com.android.documentsui.testing;
 
-import android.annotation.BoolRes;
-import android.annotation.NonNull;
-import android.annotation.PluralsRes;
-import android.annotation.StringRes;
+import androidx.annotation.BoolRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.PluralsRes;
+import androidx.annotation.StringRes;
 import android.content.res.Resources;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
diff --git a/tests/common/com/android/documentsui/testing/TestSearchViewManager.java b/tests/common/com/android/documentsui/testing/TestSearchViewManager.java
index 6c37ef7..dbc5c44 100644
--- a/tests/common/com/android/documentsui/testing/TestSearchViewManager.java
+++ b/tests/common/com/android/documentsui/testing/TestSearchViewManager.java
@@ -16,6 +16,11 @@
 
 package com.android.documentsui.testing;
 
+import static org.mockito.Mockito.mock;
+
+import android.view.View;
+import android.view.ViewGroup;
+
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.queries.CommandInterceptor;
 import com.android.documentsui.queries.SearchViewManager;
@@ -23,7 +28,7 @@
 /**
  * Test copy of {@link com.android.documentsui.queries.SearchViewManager}
  *
- * Specficially used to test whether {@link #showMenu(boolean)}
+ * Specifically used to test whether {@link #showMenu(boolean)}
  * and {@link #updateMenu()} are called.
  */
 public class TestSearchViewManager extends SearchViewManager {
@@ -37,14 +42,31 @@
         super(
                 new SearchManagerListener() {
                     @Override
-                    public void onSearchChanged(String query) { }
+                    public void onSearchChanged(String query) {
+                    }
+
                     @Override
-                    public void onSearchFinished() { }
+                    public void onSearchFinished() {
+                    }
+
                     @Override
-                    public void onSearchViewChanged(boolean opened) { }
+                    public void onSearchViewChanged(boolean opened) {
+                    }
+
+                    @Override
+                    public void onSearchChipStateChanged(View v) {
+                    }
+
+                    @Override
+                    public void onSearchViewFocusChanged(boolean hasFocus) {
+                    }
+
+                    @Override
+                    public void onSearchViewClearClicked() {
+                    }
                 },
-                new CommandInterceptor(new TestFeatures()),
-                null);
+                new CommandInterceptor(new TestFeatures()), mock(ViewGroup.class),
+                null /* savedState */);
     }
 
     @Override
diff --git a/tests/common/com/android/documentsui/testing/TestStableIdProvider.java b/tests/common/com/android/documentsui/testing/TestStableIdProvider.java
new file mode 100644
index 0000000..b1acc25
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestStableIdProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.documentsui.testing;
+
+import com.android.documentsui.DocsSelectionHelper.StableIdProvider;
+
+import java.util.List;
+
+public class TestStableIdProvider extends StableIdProvider {
+
+    private final List<String> mDocs;
+
+    public TestStableIdProvider(List<String> docs) {
+        mDocs = docs;
+    }
+
+    @Override
+    public String getKey(int position) {
+        return mDocs.get(position);
+    }
+
+    @Override
+    public int getPosition(String id) {
+        return mDocs.indexOf(id);
+    }
+}
diff --git a/tests/common/com/android/documentsui/testing/TestSupportLoaderManager.java b/tests/common/com/android/documentsui/testing/TestSupportLoaderManager.java
new file mode 100644
index 0000000..12ef540
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestSupportLoaderManager.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 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.documentsui.testing;
+
+import android.os.Bundle;
+import android.util.SparseArray;
+
+import androidx.loader.app.LoaderManager;
+import androidx.loader.content.AsyncTaskLoader;
+import androidx.loader.content.Loader;
+import androidx.loader.content.Loader.OnLoadCompleteListener;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * A test double of {@link LoaderManager} that doesn't kick off loading when {@link Loader} is
+ * created. If caller needs to kick off loading caller can obtain the loader initialized and
+ * explicitly call {@link Loader#startLoading()}.
+ *
+ * This is androidx version of TestLoaderManager.
+ */
+public class TestSupportLoaderManager extends LoaderManager {
+
+    private final SparseArray<Loader> mLoaders = new SparseArray<>();
+    private final SparseArray<OnLoadCompleteListener> mListeners = new SparseArray<>();
+
+    @Override
+    public <D> Loader<D> initLoader(int id, Bundle args,
+            LoaderCallbacks<D> callback) {
+        Loader<D> loader = mLoaders.get(id);
+        OnLoadCompleteListener<D> listener = callback::onLoadFinished;
+        if (loader == null) {
+            loader = callback.onCreateLoader(id, args);
+            mLoaders.put(id, loader);
+        } else {
+            loader.unregisterListener(mListeners.get(id));
+        }
+
+        loader.registerListener(id, listener);
+        mListeners.put(id, listener);
+
+        return loader;
+    }
+
+    @Override
+    public <D> Loader<D> restartLoader(int id, Bundle args,
+            LoaderCallbacks<D> callback) {
+        if (mLoaders.get(id) != null) {
+            destroyLoader(id);
+        }
+
+        return initLoader(id, args, callback);
+    }
+
+    @Override
+    public void destroyLoader(int id) {
+        Loader loader = getLoader(id);
+        if (loader != null) {
+            loader.abandon();
+            mLoaders.remove(id);
+            mListeners.remove(id);
+        }
+    }
+
+    @Override
+    public <D> Loader<D> getLoader(int id) {
+        return mLoaders.get(id);
+    }
+
+    @Override
+    public void markForRedelivery() {
+
+    }
+
+    public <D> OnLoadCompleteListener<D> getListener(int id) {
+        return mListeners.get(id);
+    }
+
+    public void runAsyncTaskLoader(int id) {
+        AsyncTaskLoader loader = (AsyncTaskLoader) getLoader(id);
+        loader.startLoading();
+    }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+
+    }
+}
diff --git a/tests/common/com/android/documentsui/ui/TestDialogController.java b/tests/common/com/android/documentsui/ui/TestDialogController.java
index b67ce46..190ce72 100644
--- a/tests/common/com/android/documentsui/ui/TestDialogController.java
+++ b/tests/common/com/android/documentsui/ui/TestDialogController.java
@@ -15,10 +15,11 @@
  */
 package com.android.documentsui.ui;
 
-import android.app.FragmentManager;
+import androidx.fragment.app.FragmentManager;
 
 import com.android.documentsui.base.ConfirmationCallback;
 import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.picker.ConfirmFragment;
 import com.android.documentsui.services.FileOperation;
 import com.android.documentsui.services.FileOperations;
 
@@ -34,7 +35,8 @@
     private boolean mDocumentsClipped;
     private boolean mViewInArchivesUnsupported;
     private boolean mShowOperationUnsupported;
-    private DocumentInfo mOverwriteTarget;
+    private DocumentInfo mTarget;
+    private int mConfrimType;
 
     public TestDialogController() {
         // by default, always confirm
@@ -77,8 +79,9 @@
     }
 
     @Override
-    public void confirmOverwrite(FragmentManager fm, DocumentInfo overwriteTarget) {
-        mOverwriteTarget = overwriteTarget;
+    public void confirmAction(FragmentManager fm, DocumentInfo pickTarget, int type) {
+        mTarget = pickTarget;
+        mConfrimType = type;
     }
 
     public void assertNoFileFailures() {
@@ -105,7 +108,13 @@
     }
 
     public void assertOverwriteConfirmed(DocumentInfo expected) {
-        Assert.assertEquals(expected, mOverwriteTarget);
+        Assert.assertEquals(expected, mTarget);
+        Assert.assertEquals(ConfirmFragment.TYPE_OVERWRITE, mConfrimType);
+    }
+
+    public void assertDocumentTreeConfirmed(DocumentInfo expected) {
+        Assert.assertEquals(expected, mTarget);
+        Assert.assertEquals(ConfirmFragment.TYPE_OEPN_TREE, mConfrimType);
     }
 
     public void confirmNext() {
diff --git a/tests/functional/com/android/documentsui/ActivityTest.java b/tests/functional/com/android/documentsui/ActivityTest.java
index 262ea33..18b1e2f 100644
--- a/tests/functional/com/android/documentsui/ActivityTest.java
+++ b/tests/functional/com/android/documentsui/ActivityTest.java
@@ -18,10 +18,12 @@
 
 import android.app.Activity;
 import android.app.UiAutomation;
+import android.app.UiModeManager;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
@@ -48,6 +50,7 @@
 public abstract class ActivityTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
 
     static final int TIMEOUT = 5000;
+    static final int NIGHT_MODE_CHANGE_WAIT_TIME = 1000;
 
     // Testing files. For custom ones, override initTestFiles().
     public static final String dirName1 = "Dir1";
@@ -69,6 +72,7 @@
     protected ContentResolver mResolver;
     protected DocumentsProviderHelper mDocsHelper;
     protected ContentProviderClient mClient;
+    protected UiModeManager mUiModeManager;
 
     public ActivityTest(Class<T> activityClass) {
         super(activityClass);
@@ -142,7 +146,7 @@
 
     protected void launchActivity() {
         final Intent intent = context.getPackageManager().getLaunchIntentForPackage(
-                UiBot.TARGET_PKG);
+                UiBot.targetPackageName);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
         if (getInitialRoot() != null) {
             intent.setAction(Intent.ACTION_VIEW);
@@ -181,4 +185,24 @@
         bots.directory.waitForDocument(fileName4);
         bots.directory.assertDocumentsCount(2);
     }
+
+    /**
+     * Setup test Activity UI Mode YES or not(AUTO/YES/NO) before start to testing
+     * @param uiModeNight Constant for {@link #setNightMode(int)}
+     *      0 - MODE_NIGHT_AUTO
+     *      1 - MODE_NIGHT_NO
+     *      2 - MODE_NIGHT_YES
+     */
+    protected void setSystemUiModeNight(int uiModeNight) {
+        int systemUiMode = getActivity().getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_NIGHT_MASK;
+        if(uiModeNight != systemUiMode) {
+            /* TODO since ag/4947691 enable config_lockDayNightMode to block app setNightMode()
+               create b/115315612 to handle the UiModeManager permission deny problem */
+            mUiModeManager = (UiModeManager) getActivity()
+                    .getSystemService(Context.UI_MODE_SERVICE);
+            mUiModeManager.setNightMode(uiModeNight);
+            device.waitForIdle(NIGHT_MODE_CHANGE_WAIT_TIME);
+        }
+    }
 }
diff --git a/tests/functional/com/android/documentsui/ArchiveUiTest.java b/tests/functional/com/android/documentsui/ArchiveUiTest.java
index 5c1be72..b3bebb6 100644
--- a/tests/functional/com/android/documentsui/ArchiveUiTest.java
+++ b/tests/functional/com/android/documentsui/ArchiveUiTest.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import android.support.test.filters.LargeTest;
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
 
diff --git a/tests/functional/com/android/documentsui/BandSelectionUiTest.java b/tests/functional/com/android/documentsui/BandSelectionUiTest.java
index c1b44b4..94cdef3 100644
--- a/tests/functional/com/android/documentsui/BandSelectionUiTest.java
+++ b/tests/functional/com/android/documentsui/BandSelectionUiTest.java
@@ -18,7 +18,8 @@
 
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.support.test.filters.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
 
@@ -39,8 +40,9 @@
     public void testBandSelection_allFiles() throws Exception {
         bots.main.switchToGridMode();
         Rect dirListBounds = bots.directory.findDocumentsList().getBounds();
-        Point start = new Point(dirListBounds.right - 1, dirListBounds.bottom - 1);
-        Point end = new Point(dirListBounds.left + 1, dirListBounds.top + 1);
+        Rect startDir = bots.directory.findDocument(dirName1).getBounds();
+        Point start = new Point(dirListBounds.right - 1, startDir.centerY());
+        Point end = new Point(dirListBounds.left + 1, dirListBounds.bottom - 1);
         bots.gesture.bandSelection(start, end);
 
         bots.directory.assertSelection(4);
@@ -49,11 +51,12 @@
     public void testBandSelection_someFiles() throws Exception {
         bots.main.switchToGridMode();
         Rect dirListBounds = bots.directory.findDocumentsList().getBounds();
-        Rect startDoc = bots.directory.findDocument(fileName2).getBounds();
-        // 100 pixels below bottom of file2
-        Point start = new Point(startDoc.centerX(), startDoc.bottom + 100);
-        // Top left corner
-        Point end = new Point(dirListBounds.left + 1, dirListBounds.top + 1);
+        Rect startDoc = bots.directory.findDocument(fileNameNoRename).getBounds();
+        Rect endDoc = bots.directory.findDocument(fileName1).getBounds();
+        // Start from right side of file NoRename.
+        Point start = new Point(dirListBounds.right - 1, startDoc.bottom - 1);
+        // End is center of file1
+        Point end = new Point(endDoc.centerX(), endDoc.centerY());
         bots.gesture.bandSelection(start, end);
 
         bots.directory.assertSelection(3);
diff --git a/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java b/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java
index 3351308..5deb6b7 100644
--- a/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java
+++ b/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java
@@ -27,10 +27,12 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 import com.android.documentsui.services.TestNotificationService;
 
 import java.util.concurrent.CountDownLatch;
@@ -140,6 +142,7 @@
         }
     }
 
+    @HugeLongTest
     public void testCopyDocument_Cancel() throws Exception {
         bots.roots.openRoot(ROOT_0_ID);
 
@@ -158,6 +161,7 @@
         bots.directory.waitForDocument(TARGET_FILE);
     }
 
+    @HugeLongTest
     public void testCopyDocument_CancelFromNotification() throws Exception {
         bots.roots.openRoot(ROOT_0_ID);
         bots.directory.findDocument(TARGET_FILE);
@@ -190,6 +194,7 @@
         assertTrue(bots.directory.hasDocuments(TARGET_FILE));
     }
 
+    @HugeLongTest
     public void testMoveDocument_Cancel() throws Exception {
         bots.roots.openRoot(ROOT_0_ID);
 
@@ -208,6 +213,7 @@
         bots.directory.waitForDocument(TARGET_FILE);
     }
 
+    @HugeLongTest
     public void testMoveDocument_CancelFromNotification() throws Exception {
         bots.roots.openRoot(ROOT_0_ID);
         bots.directory.findDocument(TARGET_FILE);
diff --git a/tests/functional/com/android/documentsui/ContextMenuUiTest.java b/tests/functional/com/android/documentsui/ContextMenuUiTest.java
index 1dac153..8032240 100644
--- a/tests/functional/com/android/documentsui/ContextMenuUiTest.java
+++ b/tests/functional/com/android/documentsui/ContextMenuUiTest.java
@@ -20,7 +20,8 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
 
@@ -71,7 +72,7 @@
 
     public void testContextMenu_onFile() throws Exception {
         menuItems.put("Share", true);
-        menuItems.put("Open", true);
+        menuItems.put("Open", false);
         menuItems.put("Open with", true);
         menuItems.put("Cut", true);
         menuItems.put("Copy", true);
@@ -108,8 +109,11 @@
         menuItems.put("Paste", true);
         menuItems.put("New folder", true);
         Rect dirListBounds = bots.directory.findDocumentsList().getBounds();
-        bots.directory.rightClickDocument(
-                new Point(dirListBounds.right - 1, dirListBounds.bottom - 1)); //bottom right corner
+        Rect dirBounds = bots.directory.findDocument(dirName1).getBounds();
+
+        bots.main.switchToGridMode();
+        // right side of dir1 area
+        bots.directory.rightClickDocument(new Point(dirListBounds.right - 1, dirBounds.centerY()));
         bots.menu.assertPresentMenuItems(menuItems);
     }
 }
diff --git a/tests/functional/com/android/documentsui/DirectoryMessagesUiTest.java b/tests/functional/com/android/documentsui/DirectoryMessagesUiTest.java
index fda1308..fa2ec30 100644
--- a/tests/functional/com/android/documentsui/DirectoryMessagesUiTest.java
+++ b/tests/functional/com/android/documentsui/DirectoryMessagesUiTest.java
@@ -16,9 +16,15 @@
 
 package com.android.documentsui;
 
-import android.support.test.filters.LargeTest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.text.TextUtils;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 
 @LargeTest
 public class DirectoryMessagesUiTest extends ActivityTest<FilesActivity> {
@@ -41,16 +47,18 @@
         }
         bots.directory.openDocument(DemoProvider.DIR_AUTH);
         bots.directory.assertHasMessage(
-                "To view this directory, sign in to DocumentsUI Tests");
+                "To view this directory, sign in to " + getTestAppName());
         bots.directory.assertHasMessageButtonText("SIGN IN");
     }
 
+    @HugeLongTest
     public void testInfoMessage_visible() throws Exception {
         bots.directory.openDocument(DemoProvider.DIR_INFO);
         bots.directory.assertHasMessage(DemoProvider.MSG_INFO);
-        bots.directory.assertHasMessageButtonText("DISMISS");
+        bots.directory.assertHasMessageButtonText("OK");
     }
 
+    @HugeLongTest
     public void testInfoMessage_dismissable() throws Exception {
         bots.directory.openDocument(DemoProvider.DIR_INFO);
         bots.directory.assertHasMessage(true);
@@ -58,12 +66,14 @@
         bots.directory.assertHasMessage(false);
     }
 
+    @HugeLongTest
     public void testErrorMessage_visible() throws Exception {
         bots.directory.openDocument(DemoProvider.DIR_ERROR);
         bots.directory.assertHasMessage(DemoProvider.MSG_ERROR);
-        bots.directory.assertHasMessageButtonText("DISMISS");
+        bots.directory.assertHasMessageButtonText("OK");
     }
 
+    @HugeLongTest
     public void testErrorMessage_dismissable() throws Exception {
         bots.directory.openDocument(DemoProvider.DIR_ERROR);
         bots.directory.assertHasMessage(true);
@@ -71,9 +81,18 @@
         bots.directory.assertHasMessage(false);
     }
 
+    @HugeLongTest
     public void testErrorMessage_supercedesInfoMessage() throws Exception {
         // When both error and info are returned in Directory, only show the error.
         bots.directory.openDocument(DemoProvider.DIR_ERROR_AND_INFO);
         bots.directory.assertHasMessage(DemoProvider.MSG_ERROR_AND_INFO);
     }
+
+    private String getTestAppName() {
+        final ApplicationInfo ai =
+                InstrumentationRegistry.getInstrumentation().getContext().getApplicationInfo();
+        final PackageManager pm = context.getPackageManager();
+        CharSequence result = pm.getApplicationLabel(ai);
+        return TextUtils.isEmpty(result) ? "" : result.toString();
+    }
 }
diff --git a/tests/functional/com/android/documentsui/FileCopyUiTest.java b/tests/functional/com/android/documentsui/FileCopyUiTest.java
index c0cd84f..666441a 100644
--- a/tests/functional/com/android/documentsui/FileCopyUiTest.java
+++ b/tests/functional/com/android/documentsui/FileCopyUiTest.java
@@ -20,8 +20,8 @@
 import static com.android.documentsui.base.Providers.ROOT_ID_DEVICE;
 
 import android.content.BroadcastReceiver;
-import android.content.Context;
 import android.content.ContentProviderClient;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
@@ -31,21 +31,23 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.support.test.filters.LargeTest;
 import android.text.TextUtils;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 import com.android.documentsui.services.TestNotificationService;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -252,15 +254,14 @@
         int count = 0;
         try {
             in = new ZipInputStream(res.openRawResource(resId));
-            ZipEntry zipEntry = null;
-            while ((zipEntry = in.getNextEntry()) != null && (count++ < TARGET_COUNT)) {
-                String fileName = zipEntry.getName();
+            ZipEntry archiveEntry = null;
+            while ((archiveEntry = in.getNextEntry()) != null && (count++ < TARGET_COUNT)) {
+                String fileName = archiveEntry.getName();
                 Uri uri = helper.createDocument(root, "image/png", fileName);
                 byte[] buff = new byte[1024];
                 while ((read = in.read(buff)) > 0) {
                     helper.writeAppendDocument(uri, buff);
                 }
-                in.closeEntry();
                 buff = null;
             }
         } finally {
@@ -371,6 +372,7 @@
     }
 
     // Copy Internal Storage -> Internal Storage //
+    @HugeLongTest
     public void testCopyDocuments_InternalStorage() throws Exception {
         createDocuments(StubProvider.ROOT_0_ID, rootDir0, mDocsHelper);
         copyFiles(StubProvider.ROOT_0_ID, StubProvider.ROOT_1_ID);
@@ -384,6 +386,7 @@
     }
 
     // Copy SD Card -> Internal Storage //
+    @HugeLongTest
     public void testCopyDocuments_FromSdCard() throws Exception {
         createDocuments(mSdCardLabel, mSdCardRoot, mStorageDocsHelper);
         copyFiles(mSdCardLabel, Build.MODEL);
@@ -397,6 +400,7 @@
     }
 
     // Copy Internal Storage -> SD Card //
+    @HugeLongTest
     public void testCopyDocuments_ToSdCard() throws Exception {
         createDocuments(Build.MODEL, mPrimaryRoot, mStorageDocsHelper);
         copyFiles(Build.MODEL, mSdCardLabel);
@@ -408,4 +412,18 @@
         // Check that copied files exist
         assertFilesCopied(mSdCardLabel, mSdCardRoot, mStorageDocsHelper);
     }
+
+    @HugeLongTest
+    public void testCopyDocuments_documentsDisabled() throws Exception {
+        mDocsHelper.createDocument(rootDir0, "text/plain", fileName1);
+        bots.roots.openRoot(StubProvider.ROOT_0_ID);
+        bots.directory.selectDocument(fileName1, 1);
+        device.waitForIdle();
+        bots.main.clickToolbarOverflowItem(context.getResources().getString(R.string.menu_copy));
+        device.waitForIdle();
+        bots.roots.openRoot(StubProvider.ROOT_0_ID);
+        device.waitForIdle();
+
+        assertFalse(bots.directory.findDocument(fileName1).isEnabled());
+    }
 }
diff --git a/tests/functional/com/android/documentsui/FileDeleteUiTest.java b/tests/functional/com/android/documentsui/FileDeleteUiTest.java
index fbeaf34..f4efd15 100644
--- a/tests/functional/com/android/documentsui/FileDeleteUiTest.java
+++ b/tests/functional/com/android/documentsui/FileDeleteUiTest.java
@@ -25,19 +25,21 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 import com.android.documentsui.services.TestNotificationService;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import java.util.List;
-import java.util.ArrayList;
 
 /**
 * This class test the below points
@@ -155,6 +157,7 @@
         exec.shutdown();
     }
 
+    @HugeLongTest
     public void testDeleteAllDocument() throws Exception {
         bots.roots.openRoot(ROOT_0_ID);
         bots.main.clickToolbarOverflowItem(
diff --git a/tests/functional/com/android/documentsui/FileManagementUiTest.java b/tests/functional/com/android/documentsui/FileManagementUiTest.java
index 58be747..9adffac 100644
--- a/tests/functional/com/android/documentsui/FileManagementUiTest.java
+++ b/tests/functional/com/android/documentsui/FileManagementUiTest.java
@@ -22,13 +22,15 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.Suppress;
 import android.view.KeyEvent;
 
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.Suppress;
+
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 import com.android.documentsui.sorting.SortDimension;
 import com.android.documentsui.sorting.SortModel;
 
@@ -87,6 +89,7 @@
         bots.directory.assertDocumentsAbsent("file1.png");
     }
 
+    @HugeLongTest
     public void testKeyboard_CutDocument() throws Exception {
         bots.directory.selectDocument("file1.png", 1);
         device.waitForIdle();
@@ -104,6 +107,7 @@
         bots.directory.assertDocumentsAbsent("file1.png");
     }
 
+    @HugeLongTest
     public void testKeyboard_CopyDocument() throws Exception {
         bots.directory.selectDocument("file1.png", 1);
         device.waitForIdle();
@@ -130,6 +134,7 @@
         bots.directory.waitForDocument("file1.png");
     }
 
+    @HugeLongTest
     public void testCopyLargeAmountOfFiles() throws Exception {
         // Suppress root notification. We're gonna create tons of files and it will soon crash
         // DocsUI because too many root refreshes are queued in an executor.
@@ -150,7 +155,7 @@
 
         bots.roots.openRoot(ROOT_0_ID);
         bots.directory.openDocument("test");
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.waitForDocument("0.txt");
         bots.keyboard.pressKey(
diff --git a/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java b/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java
index 9f2a52d..f8748fa 100644
--- a/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java
+++ b/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java
@@ -20,12 +20,14 @@
 import static com.android.documentsui.StubProvider.ROOT_1_ID;
 
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
-import android.support.v7.recyclerview.R;
+
+import androidx.recyclerview.R;
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 
 @LargeTest
 public class FilesActivityDefaultsUiTest extends ActivityTest<FilesActivity> {
@@ -47,14 +49,28 @@
     public void testDefaultDirectory() throws Exception {
         device.waitForIdle();
 
-        // Separate logic for "Documents" root, which presence depends on the config setting
-        if (docsRootEnabled()) {
-            bots.main.assertWindowTitle("Documents");
+        boolean defaultRootBrowse
+                = context.getResources().getBoolean(R.bool.feature_default_root_in_browse);
+
+        if (defaultRootBrowse) {
+            // Separate logic for "Documents" root, which presence depends on the config setting
+            if (docsRootEnabled()) {
+                bots.main.assertWindowTitle("Documents");
+            } else {
+                bots.main.assertWindowTitle("Downloads");
+            }
         } else {
-            bots.main.assertWindowTitle("Downloads");
+            boolean showSearchBar =
+                    context.getResources().getBoolean(R.bool.show_search_bar);
+            if (showSearchBar) {
+                bots.main.assertSearchBarShow();
+            } else {
+                bots.main.assertWindowTitle("Recent");
+            }
         }
     }
 
+    @HugeLongTest
     public void testNavigate_FromEmptyDirectory() throws Exception {
         device.waitForIdle();
 
@@ -67,6 +83,7 @@
         device.pressBack();
     }
 
+    @HugeLongTest
     public void testDefaultRoots() throws Exception {
         device.waitForIdle();
 
diff --git a/tests/functional/com/android/documentsui/FilesActivityUiTest.java b/tests/functional/com/android/documentsui/FilesActivityUiTest.java
index ac2e3aa..16dc087 100644
--- a/tests/functional/com/android/documentsui/FilesActivityUiTest.java
+++ b/tests/functional/com/android/documentsui/FilesActivityUiTest.java
@@ -19,9 +19,11 @@
 import android.app.Instrumentation;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 import com.android.documentsui.inspector.InspectorActivity;
 
 @LargeTest
@@ -55,7 +57,7 @@
     // to be able to click on it.
     public void testClickRecent() throws Exception {
         bots.roots.openRoot("Recent");
-        bots.main.assertWindowTitle("Recent");
+        bots.main.assertSearchBarShow();
     }
 
     public void testRootClick_SetsWindowTitle() throws Exception {
@@ -110,6 +112,7 @@
         monitor.waitForActivityWithTimeout(TIMEOUT);
     }
 
+    @HugeLongTest
     public void testRootChange_UpdatesSortHeader() throws Exception {
 
         // switch to separate display modes for two separate roots. Each
@@ -123,13 +126,13 @@
         // Now switch back and assert the correct mode sort header mode
         // is restored when we load the root with that display mode.
         bots.roots.openRoot("Images");
-        bots.sortHeader.assertDropdownMode();
+        bots.sort.assertHeaderHide();
         if (bots.main.inFixedLayout()) {
             bots.roots.openRoot("Videos");
-            bots.sortHeader.assertColumnMode();
+            bots.sort.assertHeaderShow();
         } else {
             bots.roots.openRoot("Videos");
-            bots.sortHeader.assertDropdownMode();
+            bots.sort.assertHeaderHide();
         }
     }
 }
diff --git a/tests/functional/com/android/documentsui/FingerSelectionUiTest.java b/tests/functional/com/android/documentsui/FingerSelectionUiTest.java
new file mode 100644
index 0000000..69b473b
--- /dev/null
+++ b/tests/functional/com/android/documentsui/FingerSelectionUiTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 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.documentsui;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.documentsui.files.FilesActivity;
+
+@LargeTest
+public class FingerSelectionUiTest extends ActivityTest<FilesActivity> {
+
+    public FingerSelectionUiTest() {
+        super(FilesActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        initTestFiles();
+        bots.roots.closeDrawer();
+    }
+
+    public void testFingerSelection_outOfRange() throws Exception {
+        bots.main.switchToGridMode();
+        Rect dirListBounds = bots.directory.findDocumentsList().getBounds();
+        Rect firstDoc = bots.directory.findDocument(fileName1).getBounds();
+        // Start from list right bottom.
+        Point start = new Point(firstDoc.centerX(), firstDoc.centerY());
+        // End is center of file1
+        Point end = new Point(dirListBounds.right, dirListBounds.bottom);
+        bots.gesture.fingerSelection(start, end);
+
+        bots.directory.assertSelection(3);
+    }
+}
diff --git a/tests/functional/com/android/documentsui/GestureSelectionUiTest.java b/tests/functional/com/android/documentsui/GestureSelectionUiTest.java
index a8a1aec..4c2b403 100644
--- a/tests/functional/com/android/documentsui/GestureSelectionUiTest.java
+++ b/tests/functional/com/android/documentsui/GestureSelectionUiTest.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import android.support.test.filters.LargeTest;
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
 
diff --git a/tests/functional/com/android/documentsui/InspectorUiTest.java b/tests/functional/com/android/documentsui/InspectorUiTest.java
index a228de2..99d0ae0 100644
--- a/tests/functional/com/android/documentsui/InspectorUiTest.java
+++ b/tests/functional/com/android/documentsui/InspectorUiTest.java
@@ -18,7 +18,8 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.provider.DocumentsContract;
-import android.support.test.filters.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.bots.UiBot;
 import com.android.documentsui.inspector.InspectorActivity;
@@ -43,7 +44,7 @@
             return;
         }
         final Intent intent = context.getPackageManager().getLaunchIntentForPackage(
-                UiBot.TARGET_PKG);
+                UiBot.targetPackageName);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
         Uri uri = DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, TEST_DOC_NAME);
         intent.setData(uri);
@@ -68,7 +69,7 @@
                 getActivity());
         bots.inspector.assertRowEquals(
                 getActivity().getString(R.string.directory_items),
-                "4",
+                InspectorProvider.NUMBER_OF_ITEMS,
                 getActivity());
     }
 }
diff --git a/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java b/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java
index 62e5fb6..9302e52 100644
--- a/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java
+++ b/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java
@@ -20,12 +20,13 @@
 import android.app.DownloadManager.Request;
 import android.content.Context;
 import android.net.Uri;
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.Suppress;
 import android.support.test.uiautomator.Configurator;
 import android.support.test.uiautomator.UiObject;
 import android.view.MotionEvent;
 
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.Suppress;
+
 import com.android.documentsui.files.FilesActivity;
 
 // TODO: As of this writing all tests in this class are disabled. Please fix.
diff --git a/tests/functional/com/android/documentsui/InternalStorageUiTest.java b/tests/functional/com/android/documentsui/InternalStorageUiTest.java
new file mode 100644
index 0000000..384b0ad
--- /dev/null
+++ b/tests/functional/com/android/documentsui/InternalStorageUiTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 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.documentsui;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.documentsui.base.Providers;
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.State;
+import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
+
+/**
+ * A Ui test will do tests in the internal storage root. It is implemented because some operations
+ * is failed and its result will different from the test on the StubProvider. b/115304092 is a
+ * example which only happen on root from ExternalStorageProvidrer.
+ */
+@LargeTest
+public class InternalStorageUiTest extends ActivityTest<FilesActivity> {
+
+    private static final String fileName = "!Test3345678";
+    private static final String newFileName = "!9527Test";
+    private RootInfo rootPrimary;
+
+    public InternalStorageUiTest() {
+        super(FilesActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mClient = mResolver.acquireUnstableContentProviderClient(Providers.AUTHORITY_STORAGE);
+        mDocsHelper = new DocumentsProviderHelper(Providers.AUTHORITY_STORAGE, mClient);
+        rootPrimary = mDocsHelper.getRoot(Providers.ROOT_ID_DEVICE);
+
+        // If Internal Storage is not shown, turn on.
+        State state = ((FilesActivity) getActivity()).getDisplayState();
+        if (!state.showAdvanced) {
+            bots.main.clickToolbarOverflowItem(
+                    context.getResources().getString(R.string.menu_advanced_show));
+        }
+
+        bots.roots.openRoot(rootPrimary.title);
+        deleteTestFiles();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        deleteTestFiles();
+        super.tearDown();
+    }
+
+    @HugeLongTest
+    public void testRenameFile() throws Exception {
+        createTestFiles();
+
+        bots.directory.selectDocument(fileName);
+        device.waitForIdle();
+
+        bots.main.clickRename();
+
+        bots.main.setDialogText(newFileName);
+        device.waitForIdle();
+
+        bots.keyboard.pressEnter();
+
+        bots.directory.assertDocumentsAbsent(fileName);
+        bots.directory.assertDocumentsPresent(newFileName);
+        // Snackbar will not show if no exception.
+        assertNull(bots.directory.getSnackbar(context.getString(R.string.rename_error)));
+    }
+
+    private void createTestFiles() {
+        mDocsHelper.createFolder(rootPrimary, fileName);
+    }
+
+    private void deleteTestFiles() throws Exception {
+        boolean selected = false;
+        // Delete the added file for not affect user and also avoid error on next test.
+        if (bots.directory.hasDocuments(fileName)) {
+            bots.directory.selectDocument(fileName);
+            device.waitForIdle();
+            selected = true;
+        }
+        if (bots.directory.hasDocuments(newFileName)) {
+            bots.directory.selectDocument(newFileName);
+            device.waitForIdle();
+            selected = true;
+        }
+        if (selected) {
+            bots.main.clickDelete();
+            device.waitForIdle();
+            bots.main.clickDialogOkButton();
+        }
+    }
+}
diff --git a/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java b/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java
index cef7913..91364fa 100644
--- a/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java
+++ b/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java
@@ -17,10 +17,11 @@
 package com.android.documentsui;
 
 import android.os.RemoteException;
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.Suppress;
 import android.view.KeyEvent;
 
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.Suppress;
+
 import com.android.documentsui.files.FilesActivity;
 
 @LargeTest
diff --git a/tests/functional/com/android/documentsui/PickerPreviewAllTypeUiTest.java b/tests/functional/com/android/documentsui/PickerPreviewAllTypeUiTest.java
new file mode 100644
index 0000000..fe5ddb3
--- /dev/null
+++ b/tests/functional/com/android/documentsui/PickerPreviewAllTypeUiTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2018 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.documentsui;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Intent;
+import android.provider.DocumentsContract;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.bots.UiBot;
+import com.android.documentsui.picker.PickActivity;
+
+@LargeTest
+public class PickerPreviewAllTypeUiTest extends ActivityTest<PickActivity> {
+
+    private boolean mHasQuickViewer;
+
+    public PickerPreviewAllTypeUiTest() {
+        super(PickActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        initTestFiles();
+
+        mHasQuickViewer = Shared.hasQuickViewer(context);
+    }
+
+    @Override
+    protected void launchActivity() {
+        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(
+                UiBot.targetPackageName);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setAction(Intent.ACTION_GET_CONTENT);
+        if (getInitialRoot() != null) {
+            intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, getInitialRoot().getUri());
+        }
+        intent.setType("*/*");
+        setActivityIntent(intent);
+        getActivity();  // Launch the activity.
+    }
+
+    public void testPreviewInvisible_noQuickViewer_gridMode() throws Exception {
+        if (mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToGridMode();
+        assertTrue(bots.directory.findDocument(fileName1).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(fileName1));
+    }
+
+    public void testPreviewInvisible_noQuickViewer_listMode() throws Exception {
+        if (mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToListMode();
+        assertTrue(bots.directory.findDocument(fileName1).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(fileName1));
+    }
+
+    public void testPreviewInvisible_directory_gridMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToGridMode();
+        assertTrue(bots.directory.findDocument(dirName1).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(dirName1));
+    }
+
+    public void testPreviewInvisible_directory_listMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToListMode();
+        assertTrue(bots.directory.findDocument(dirName1).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(dirName1));
+    }
+
+    public void testPreviewVisible_allType_girdMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToGridMode();
+        assertTrue(bots.directory.findDocument(fileName1).isEnabled());
+        assertTrue(bots.directory.hasDocumentPreview(fileName1));
+        assertTrue(bots.directory.findDocument(fileName2).isEnabled());
+        assertTrue(bots.directory.hasDocumentPreview(fileName2));
+    }
+
+    public void testPreviewVisible_allType_listMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToListMode();
+        assertTrue(bots.directory.findDocument(fileName1).isEnabled());
+        assertTrue(bots.directory.hasDocumentPreview(fileName1));
+        assertTrue(bots.directory.findDocument(fileName2).isEnabled());
+        assertTrue(bots.directory.hasDocumentPreview(fileName2));
+    }
+}
diff --git a/tests/functional/com/android/documentsui/PickerPreviewTextUiTest.java b/tests/functional/com/android/documentsui/PickerPreviewTextUiTest.java
new file mode 100644
index 0000000..af6a3c5
--- /dev/null
+++ b/tests/functional/com/android/documentsui/PickerPreviewTextUiTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2018 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.documentsui;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Intent;
+import android.provider.DocumentsContract;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.bots.UiBot;
+import com.android.documentsui.picker.PickActivity;
+
+@LargeTest
+public class PickerPreviewTextUiTest extends ActivityTest<PickActivity>{
+
+    private boolean mHasQuickViewer;
+
+    public PickerPreviewTextUiTest() {
+        super(PickActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        initTestFiles();
+
+        mHasQuickViewer = Shared.hasQuickViewer(context);
+    }
+
+    @Override
+    protected void launchActivity() {
+        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(
+                UiBot.targetPackageName);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setAction(Intent.ACTION_GET_CONTENT);
+        if (getInitialRoot() != null) {
+            intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, getInitialRoot().getUri());
+        }
+        intent.setType("text/*");
+        setActivityIntent(intent);
+        getActivity();  // Launch the activity.
+    }
+
+    public void testPreviewInvisible_disabled_gridMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToGridMode();
+        assertFalse(bots.directory.findDocument(fileName2).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(fileName2));
+    }
+
+    public void testPreviewInvisible_disabled_listMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToListMode();
+        assertFalse(bots.directory.findDocument(fileName2).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(fileName2));
+    }
+
+    public void testPreviewInvisible_directory_gridMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToGridMode();
+        assertTrue(bots.directory.findDocument(dirName1).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(dirName1));
+    }
+
+    public void testPreviewInvisible_directory_listMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToListMode();
+        assertTrue(bots.directory.findDocument(dirName1).isEnabled());
+        assertFalse(bots.directory.hasDocumentPreview(dirName1));
+    }
+
+    public void testPreviewVisible_enabled_gridMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToGridMode();
+        assertTrue(bots.directory.findDocument(fileName1).isEnabled());
+        assertTrue(bots.directory.hasDocumentPreview(fileName1));
+    }
+
+    public void testPreviewVisible_enabled_listMode() throws Exception {
+        if (!mHasQuickViewer) {
+            return;
+        }
+
+        bots.main.switchToListMode();
+        assertTrue(bots.directory.findDocument(fileName1).isEnabled());
+        assertTrue(bots.directory.hasDocumentPreview(fileName1));
+    }
+}
diff --git a/tests/functional/com/android/documentsui/RenameDocumentUiTest.java b/tests/functional/com/android/documentsui/RenameDocumentUiTest.java
index 90f1a82..58b2e58 100644
--- a/tests/functional/com/android/documentsui/RenameDocumentUiTest.java
+++ b/tests/functional/com/android/documentsui/RenameDocumentUiTest.java
@@ -16,9 +16,10 @@
 
 package com.android.documentsui;
 
-import android.support.test.filters.LargeTest;
 import android.support.test.uiautomator.UiObjectNotFoundException;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.documentsui.files.FilesActivity;
 
 @LargeTest
diff --git a/tests/functional/com/android/documentsui/SearchViewUiTest.java b/tests/functional/com/android/documentsui/SearchViewUiTest.java
index d7ffe7c..9a151f7 100644
--- a/tests/functional/com/android/documentsui/SearchViewUiTest.java
+++ b/tests/functional/com/android/documentsui/SearchViewUiTest.java
@@ -19,11 +19,12 @@
 import static com.android.documentsui.StubProvider.ROOT_0_ID;
 import static com.android.documentsui.StubProvider.ROOT_1_ID;
 
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.Suppress;
-import android.support.v7.recyclerview.R;
+import androidx.recyclerview.R;
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.Suppress;
 
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 
 @LargeTest
 public class SearchViewUiTest extends ActivityTest<FilesActivity> {
@@ -46,27 +47,43 @@
     public void testSearchIconVisible() throws Exception {
         // The default root (root 0) supports search
         bots.search.assertInputExists(false);
+        bots.search.assertFragmentInputExists(false);
         bots.search.assertIconVisible(true);
     }
 
+    @HugeLongTest
     public void testSearchIconHidden() throws Exception {
         bots.roots.openRoot(ROOT_1_ID);  // root 1 doesn't support search
 
         bots.search.assertIconVisible(false);
         bots.search.assertInputExists(false);
+        bots.search.assertFragmentInputExists(false);
     }
 
     public void testSearchView_ExpandsOnClick() throws Exception {
         bots.search.clickIcon();
         device.waitForIdle();
 
-        bots.search.assertInputExists(true);
-        bots.search.assertInputFocused(true);
+        bots.search.assertFragmentInputExists(true);
+        bots.search.assertFragmentInputFocused(true);
 
         // FIXME: Matchers fail the not-present check if we've ever clicked this.
         // bots.search.assertIconVisible(false);
     }
 
+    public void testSearchView_ShouldHideOptionMenuOnExpanding() throws Exception {
+        bots.search.clickIcon();
+        device.waitForIdle();
+
+        bots.search.assertFragmentInputExists(true);
+        bots.search.assertFragmentInputFocused(true);
+        device.waitForIdle();
+
+        assertFalse(bots.menu.hasMenuItem("Grid view"));
+        assertFalse(bots.menu.hasMenuItem("List view"));
+        assertFalse(bots.menu.hasMenuItemByDesc("More options"));
+    }
+
     public void testSearchView_CollapsesOnBack() throws Exception {
         bots.search.clickIcon();
         device.pressBack();
@@ -74,6 +91,7 @@
 
         bots.search.assertIconVisible(true);
         bots.search.assertInputExists(false);
+        bots.search.assertFragmentInputExists(false);
     }
 
     public void testSearchView_ClearsTextOnBack() throws Exception {
@@ -88,6 +106,34 @@
 
         bots.search.assertIconVisible(true);
         bots.search.assertInputExists(false);
+        bots.search.assertFragmentInputExists(false);
+    }
+
+    public void testSearchView_ClearsSearchOnBack() throws Exception {
+        bots.search.clickIcon();
+        bots.search.setInputText("file1");
+        bots.keyboard.pressEnter();
+        device.waitForIdle();
+
+        device.pressBack();
+
+        bots.search.assertIconVisible(true);
+        bots.search.assertInputExists(false);
+        bots.search.assertFragmentInputExists(false);
+    }
+
+    public void testSearchView_ClearsAutoSearchOnBack() throws Exception {
+        bots.search.clickIcon();
+        bots.search.setInputText("chocolate");
+        //Wait for auto search result, it should be no results and show holder message.
+        bots.directory.waitForHolderMessage();
+
+        device.pressBack();
+        device.pressBack();
+
+        bots.search.assertIconVisible(true);
+        bots.search.assertInputExists(false);
+        bots.search.assertFragmentInputExists(false);
     }
 
     public void testSearchView_StateAfterSearch() throws Exception {
@@ -165,4 +211,33 @@
 
         assertDefaultContentOfTestDir0();
     }
+
+    public void testSearchHistory_showAfterSearchViewClear() throws Exception {
+        bots.search.clickIcon();
+        bots.search.setInputText("chocolate");
+
+        bots.keyboard.pressEnter();
+        device.waitForIdle();
+
+        bots.search.clickSearchViewClearButton();
+        device.waitForIdle();
+
+        bots.search.assertFragmentInputExists(true);
+        bots.search.assertFragmentInputFocused(true);
+    }
+
+    public void testSearchHistory_showAfterFragmentSearchViewClear() throws Exception {
+        bots.search.clickIcon();
+        bots.search.setInputText("chocolate");
+
+        bots.keyboard.pressEnter();
+        device.waitForIdle();
+
+        bots.search.clickIcon();
+        bots.search.clickFragmentSearchViewClearButton();
+        device.waitForIdle();
+
+        bots.search.assertFragmentInputExists(true);
+        bots.search.assertFragmentInputFocused(true);
+    }
 }
diff --git a/tests/functional/com/android/documentsui/SidebarUiTest.java b/tests/functional/com/android/documentsui/SidebarUiTest.java
index c21c853..3943a46 100644
--- a/tests/functional/com/android/documentsui/SidebarUiTest.java
+++ b/tests/functional/com/android/documentsui/SidebarUiTest.java
@@ -19,10 +19,11 @@
 import static com.android.documentsui.StubProvider.ROOT_0_ID;
 import static com.android.documentsui.StubProvider.ROOT_1_ID;
 
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.Suppress;
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.Suppress;
 
 import com.android.documentsui.files.FilesActivity;
+import com.android.documentsui.filters.HugeLongTest;
 
 @LargeTest
 public class SidebarUiTest extends ActivityTest<FilesActivity> {
@@ -39,6 +40,7 @@
         initTestFiles();
     }
 
+    @HugeLongTest
     public void testRootTapped_GoToRootFromChildDir() throws Exception {
         bots.directory.openDocument(dirName1);
         bots.breadcrumb.assertTitle(dirName1);
diff --git a/tests/functional/com/android/documentsui/SortDocumentUiTest.java b/tests/functional/com/android/documentsui/SortDocumentUiTest.java
index ed51927..05878bb 100644
--- a/tests/functional/com/android/documentsui/SortDocumentUiTest.java
+++ b/tests/functional/com/android/documentsui/SortDocumentUiTest.java
@@ -17,7 +17,8 @@
 package com.android.documentsui;
 
 import android.net.Uri;
-import android.support.test.filters.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.documentsui.files.FilesActivity;
 import com.android.documentsui.sorting.SortDimension;
@@ -99,7 +100,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC);
     }
@@ -109,7 +110,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC);
     }
@@ -119,7 +120,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC);
     }
@@ -129,7 +130,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.assertOrder(DIRS, FILES);
     }
@@ -139,7 +140,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC);
     }
@@ -149,7 +150,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_FILE_TYPE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_TYPE_ASC);
     }
@@ -159,7 +160,7 @@
 
         bots.main.switchToListMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_FILE_TYPE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_TYPE_DESC);
     }
@@ -169,7 +170,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC);
     }
@@ -179,7 +180,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC);
     }
@@ -189,7 +190,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC);
     }
@@ -199,7 +200,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.assertOrder(DIRS, FILES);
     }
@@ -209,7 +210,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC);
     }
@@ -219,7 +220,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_FILE_TYPE, SortDimension.SORT_DIRECTION_ASCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_TYPE_ASC);
     }
@@ -229,7 +230,7 @@
 
         bots.main.switchToGridMode();
 
-        bots.sortHeader.sortBy(
+        bots.sort.sortBy(
                 SortModel.SORT_DIMENSION_ID_FILE_TYPE, SortDimension.SORT_DIRECTION_DESCENDING);
         bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_TYPE_DESC);
     }
diff --git a/tests/res/raw/hello_7z b/tests/res/raw/hello_7z
new file mode 100644
index 0000000..249330b
--- /dev/null
+++ b/tests/res/raw/hello_7z
Binary files differ
diff --git a/tests/res/raw/hello_tar b/tests/res/raw/hello_tar
new file mode 100644
index 0000000..cdc2310
--- /dev/null
+++ b/tests/res/raw/hello_tar
Binary files differ
diff --git a/tests/res/raw/hello_tar_br b/tests/res/raw/hello_tar_br
new file mode 100644
index 0000000..1104a25
--- /dev/null
+++ b/tests/res/raw/hello_tar_br
Binary files differ
diff --git a/tests/res/raw/hello_tar_bz2 b/tests/res/raw/hello_tar_bz2
new file mode 100644
index 0000000..37464da
--- /dev/null
+++ b/tests/res/raw/hello_tar_bz2
Binary files differ
diff --git a/tests/res/raw/hello_tar_xz b/tests/res/raw/hello_tar_xz
new file mode 100644
index 0000000..5b5f750
--- /dev/null
+++ b/tests/res/raw/hello_tar_xz
Binary files differ
diff --git a/tests/res/raw/hello_tgz b/tests/res/raw/hello_tgz
new file mode 100644
index 0000000..93f0194
--- /dev/null
+++ b/tests/res/raw/hello_tgz
Binary files differ
diff --git a/tests/res/raw/images_7z b/tests/res/raw/images_7z
new file mode 100644
index 0000000..a86ea13
--- /dev/null
+++ b/tests/res/raw/images_7z
Binary files differ
diff --git a/tests/res/raw/images_tar b/tests/res/raw/images_tar
new file mode 100644
index 0000000..e2fb86b
--- /dev/null
+++ b/tests/res/raw/images_tar
Binary files differ
diff --git a/tests/res/raw/images_tar_br b/tests/res/raw/images_tar_br
new file mode 100644
index 0000000..4839e7e
--- /dev/null
+++ b/tests/res/raw/images_tar_br
Binary files differ
diff --git a/tests/res/raw/images_tar_xz b/tests/res/raw/images_tar_xz
new file mode 100644
index 0000000..64f4e43
--- /dev/null
+++ b/tests/res/raw/images_tar_xz
Binary files differ
diff --git a/tests/res/raw/images_tgz b/tests/res/raw/images_tgz
new file mode 100644
index 0000000..de42184
--- /dev/null
+++ b/tests/res/raw/images_tgz
Binary files differ
diff --git a/tests/res/values/attrs.xml b/tests/res/values/attrs.xml
new file mode 100644
index 0000000..54d5828
--- /dev/null
+++ b/tests/res/values/attrs.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<resources>
+
+    <declare-styleable name="ThemeColor">
+        <attr name="android:colorBackground" />
+        <attr name="android:colorPrimary" />
+        <attr name="android:colorControlNormal" />
+        <attr name="android:textColorPrimary" />
+    </declare-styleable>
+
+    <declare-styleable name="SystemWindow">
+        <attr name="android:statusBarColor" />
+        <attr name="android:navigationBarColor" />
+        <attr name="android:windowBackground" />
+        <attr name="android:windowLightStatusBar" />
+        <attr name="android:windowLightNavigationBar" />
+    </declare-styleable>
+
+</resources>
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
index d9c5517..3d1e0db 100644
--- a/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/AbstractActionHandlerTest.java
@@ -18,6 +18,7 @@
 
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
+
 import static org.junit.Assert.assertEquals;
 
 import android.content.Intent;
@@ -25,14 +26,15 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Path;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.files.LauncherActivity;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 import com.android.documentsui.sorting.SortDimension;
 import com.android.documentsui.sorting.SortModel;
 import com.android.documentsui.testing.DocumentStackAsserts;
@@ -46,6 +48,8 @@
 import org.junit.runner.RunWith;
 
 import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * A unit test *for* AbstractActionHandler, not an abstract test baseclass.
@@ -77,7 +81,8 @@
             }
 
             @Override
-            public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
+            public boolean openItem(
+                    ItemDetails<String> doc, @ViewType int type, @ViewType int fallback) {
                 throw new UnsupportedOperationException();
             }
 
@@ -255,8 +260,11 @@
                 .setNextChildDocumentsReturns(TestEnv.FILE_APK, TestEnv.FILE_GIF);
 
         mHandler.loadDocumentsForCurrentStack();
-        mActivity.loaderManager.runAsyncTaskLoader(AbstractActionHandler.LOADER_ID);
+        CountDownLatch latch = new CountDownLatch(1);
+        mEnv.model.addUpdateListener(event -> latch.countDown());
+        mActivity.supportLoaderManager.runAsyncTaskLoader(AbstractActionHandler.LOADER_ID);
 
+        latch.await(1, TimeUnit.SECONDS);
         assertEquals(2, mEnv.model.getItemCount());
         String[] modelIds = mEnv.model.getModelIds();
         assertEquals(TestEnv.FILE_APK, mEnv.model.getDocument(modelIds[0]));
@@ -277,4 +285,13 @@
 
         assertTrue(listener.getLastValue().hasException());
     }
+
+    @Test
+    public void testPreviewItem_throwException() throws Exception {
+        try {
+            mHandler.previewItem(null);
+            fail("Should have thrown UnsupportedOperationException.");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
 }
diff --git a/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java b/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java
index 42f6bb0..c06201b 100644
--- a/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java
+++ b/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java
@@ -21,16 +21,12 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView.Adapter;
+import androidx.recyclerview.selection.Selection;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.DocsSelectionHelper.DelegateFactory;
-import com.android.documentsui.selection.DefaultSelectionHelper;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -40,7 +36,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Tests for the specialized behaviors provided by DocsSelectionManager.
@@ -57,20 +52,16 @@
     public void setup() {
         mCreated = new ArrayList<>();
         mFactory = new DelegateFactory() {
-            @Override
-            TestSelectionManager create(
-                    int mode,
-                    Adapter<?> adapter,
-                    StableIdProvider stableIds,
-                    SelectionPredicate canSetState) {
 
+            @Override
+            TestSelectionManager create(SelectionTracker<String> selectionTracker) {
                 TestSelectionManager mgr = new TestSelectionManager();
                 mCreated.add(mgr);
                 return mgr;
             }
         };
 
-        mSelectionMgr = new DocsSelectionHelper(mFactory, DefaultSelectionHelper.MODE_MULTIPLE);
+        mSelectionMgr = new DocsSelectionHelper(mFactory);
     }
 
     @Test
@@ -82,16 +73,16 @@
 
     @Test
     public void testReset_CreatesNewInstances() {
-        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
-        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+        resetSelectionHelper();
+        resetSelectionHelper();
 
         assertCreated(2);
     }
 
     @Test
     public void testReset_ClearsPreviousSelection() {
-        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
-        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+        resetSelectionHelper();
+        resetSelectionHelper();
 
         mCreated.get(0).assertCleared(true);
         mCreated.get(1).assertCleared(false);
@@ -99,7 +90,7 @@
 
     @Test
     public void testReplaceSelection() {
-        mSelectionMgr.reset(null, null, null);  // nulls are passed to factory. We ignore.
+        resetSelectionHelper();
 
         List<String> ids = new ArrayList<>();
         ids.add("poodles");
@@ -113,7 +104,11 @@
         assertEquals(count, mCreated.size());
     }
 
-    private static final class TestSelectionManager extends SelectionHelper {
+    private void resetSelectionHelper() {
+        mSelectionMgr.reset(null); // nulls are passed to factory. We ignore.
+    }
+
+    private static final class TestSelectionManager extends DummySelectionTracker<String> {
 
         private boolean mCleared;
         private Map<String, Boolean> mSelected = new HashMap<>();
@@ -141,12 +136,7 @@
         }
 
         @Override
-        public Selection getSelection() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void copySelection(Selection dest) {
+        public Selection<String> getSelection() {
             throw new UnsupportedOperationException();
         }
 
@@ -156,7 +146,7 @@
         }
 
         @Override
-        public void restoreSelection(Selection other) {
+        public void restoreSelection(Selection<String> other) {
             throw new UnsupportedOperationException();
         }
 
@@ -169,8 +159,9 @@
         }
 
         @Override
-        public void clearSelection() {
+        public boolean clearSelection() {
             mCleared = true;
+            return true;
         }
 
         @Override
@@ -182,50 +173,5 @@
         public boolean deselect(String itemId) {
             throw new UnsupportedOperationException();
         }
-
-        @Override
-        public void startRange(int pos) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void extendRange(int pos) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void endRange() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isRangeActive() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void anchorRange(int position) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void extendProvisionalRange(int pos) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void clearProvisionalSelection() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void mergeProvisionalSelection() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void setProvisionalSelection(Set<String> newSelection) {
-            throw new UnsupportedOperationException();
-        }
     }
 }
diff --git a/tests/unit/com/android/documentsui/DragAndDropManagerTests.java b/tests/unit/com/android/documentsui/DragAndDropManagerTests.java
index deea971..3c30bf3 100644
--- a/tests/unit/com/android/documentsui/DragAndDropManagerTests.java
+++ b/tests/unit/com/android/documentsui/DragAndDropManagerTests.java
@@ -26,14 +26,15 @@
 import android.content.ClipDescription;
 import android.graphics.drawable.Drawable;
 import android.os.PersistableBundle;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.Pair;
 import android.view.KeyEvent;
 import android.view.View;
 
-import com.android.documentsui.DragAndDropManager.State;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.DragAndDropManager.RuntimeDragAndDropManager;
+import com.android.documentsui.DragAndDropManager.State;
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.services.FileOperationService;
diff --git a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java b/tests/unit/com/android/documentsui/DragScrollListenerTest.java
similarity index 96%
rename from tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
rename to tests/unit/com/android/documentsui/DragScrollListenerTest.java
index f0e9f9a..9519cae 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
+++ b/tests/unit/com/android/documentsui/DragScrollListenerTest.java
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.dirlist;
+package com.android.documentsui;
 
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.DragEvent;
 import android.view.View;
 
-import com.android.documentsui.ItemDragListener;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.ViewAutoScroller.ScrollerCallbacks;
 import com.android.documentsui.testing.DragEvents;
 import com.android.documentsui.testing.Views;
 
diff --git a/tests/unit/com/android/documentsui/FileTypeMapTest.java b/tests/unit/com/android/documentsui/FileTypeMapTest.java
deleted file mode 100644
index 38728e3..0000000
--- a/tests/unit/com/android/documentsui/FileTypeMapTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.annotation.StringRes;
-import android.content.Context;
-import android.content.res.Resources;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import libcore.net.MimeMap;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class FileTypeMapTest {
-
-    private Resources mRes;
-    private FileTypeMap mMap;
-
-    @Before
-    public void setUp() {
-        Context context = InstrumentationRegistry.getTargetContext();
-        mRes = context.getResources();
-        mMap = new FileTypeMap(context);
-    }
-
-    @Test
-    public void testPlainTextType() {
-        String expected = mRes.getString(R.string.txt_file_type);
-        assertEquals(expected, mMap.lookup("text/plain"));
-    }
-
-    @Test
-    public void testPortableDocumentFormatType() {
-        String expected = mRes.getString(R.string.pdf_file_type);
-        assertEquals(expected, mMap.lookup("application/pdf"));
-    }
-
-    @Test
-    public void testMsWordType() {
-        String expected = mRes.getString(R.string.word_file_type);
-        assertEquals(expected, mMap.lookup("application/msword"));
-    }
-
-    @Test
-    public void testGoogleDocType() {
-        String expected = mRes.getString(R.string.gdoc_file_type);
-        assertEquals(expected, mMap.lookup("application/vnd.google-apps.document"));
-    }
-
-    @Test
-    public void testZipType() {
-        final String mime = "application/zip";
-        String expected = getExtensionTypeFromExtension(R.string.archive_file_type, "Zip");
-        assertEquals(expected, mMap.lookup(mime));
-    }
-
-    @Test
-    public void testMp3Type() {
-        final String mime = "audio/mpeg";
-        String expected = getExtensionTypeFromMime(R.string.audio_extension_file_type, mime);
-        assertEquals(expected, mMap.lookup(mime));
-    }
-
-    @Test
-    public void testMkvType() {
-        final String mime = "video/avi";
-        String expected = getExtensionTypeFromMime(R.string.video_extension_file_type, mime);
-        assertEquals(expected, mMap.lookup(mime));
-    }
-
-    @Test
-    public void testJpgType() {
-        final String mime = "image/jpeg";
-        String expected = getExtensionTypeFromMime(R.string.image_extension_file_type, mime);
-        assertEquals(expected, mMap.lookup(mime));
-    }
-
-    @Test
-    public void testOggType() {
-        final String mime = "application/ogg";
-        String expected = getExtensionTypeFromMime(R.string.audio_extension_file_type, mime);
-        assertEquals(expected, mMap.lookup("application/ogg"));
-    }
-
-    @Test
-    public void testFlacType() {
-        final String mime = "application/x-flac";
-        String expected = getExtensionTypeFromMime(R.string.audio_extension_file_type, mime);
-        assertEquals(expected, mMap.lookup(mime));
-    }
-
-    private String getExtensionTypeFromMime(@StringRes int formatStringId, String mime) {
-        MimeMap mimeMap = MimeMap.getDefault();
-        final String extension = mimeMap.guessExtensionFromMimeType(mime).toUpperCase();
-        return getExtensionTypeFromExtension(formatStringId, extension);
-    }
-
-    private String getExtensionTypeFromExtension(@StringRes int formatStringId, String extension) {
-        final String format = mRes.getString(formatStringId);
-        return String.format(format, extension);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/FocusManagerTest.java b/tests/unit/com/android/documentsui/FocusManagerTest.java
index b386f82..15f703d 100644
--- a/tests/unit/com/android/documentsui/FocusManagerTest.java
+++ b/tests/unit/com/android/documentsui/FocusManagerTest.java
@@ -16,18 +16,18 @@
 
 package com.android.documentsui;
 
-import android.support.v7.widget.RecyclerView;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.documentsui.base.Features;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.documentsui.dirlist.TestData;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.testing.TestModel;
-import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestFeatures;
 import com.android.documentsui.testing.TestGridLayoutManager;
+import com.android.documentsui.testing.TestModel;
 import com.android.documentsui.testing.TestRecyclerView;
+import com.android.documentsui.testing.Views;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -42,7 +42,7 @@
     private FocusManager mManager;
     private TestRecyclerView mView;
     private TestGridLayoutManager mTestGridLayoutManager;
-    private SelectionHelper mSelectionMgr;
+    private SelectionTracker<String> mSelectionMgr;
     private TestFeatures mFeatures;
 
     @Override
@@ -88,4 +88,32 @@
         mSelectionMgr.select("0");
         assertFalse(mManager.focusDirectoryList());
     }
+
+    public void testFocusDirectoryList_invalidContentScope() {
+        mManager = new FocusManager(
+                mFeatures, SelectionHelpers.createTestInstance(), null, null, 0);
+        // pass if no exception is thrown.
+        mManager.focusDirectoryList();
+    }
+
+    public void testOnFocusChange_invalidContentScope() {
+        mManager = new FocusManager(
+                mFeatures, SelectionHelpers.createTestInstance(), null, null, 0);
+        // pass if no exception is thrown.
+        mManager.onFocusChange(Views.createTestView(), true);
+    }
+
+    public void testClearFocus_invalidContentScope() {
+        mManager = new FocusManager(
+                mFeatures, SelectionHelpers.createTestInstance(), null, null, 0);
+        // pass if no exception is thrown.
+        mManager.clearFocus();
+    }
+
+    public void testFocusDocument_invalidContentScope() {
+        mManager = new FocusManager(
+                mFeatures, SelectionHelpers.createTestInstance(), null, null, 0);
+        // pass if no exception is thrown.
+        mManager.focusDocument(Integer.toString(0));
+    }
 }
diff --git a/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java b/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java
new file mode 100644
index 0000000..0770e02
--- /dev/null
+++ b/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2018 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.documentsui;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.State;
+import com.android.documentsui.sorting.SortDimension;
+import com.android.documentsui.sorting.SortModel;
+import com.android.documentsui.testing.ActivityManagers;
+import com.android.documentsui.testing.TestEnv;
+import com.android.documentsui.testing.TestFileTypeLookup;
+import com.android.documentsui.testing.TestImmediateExecutor;
+import com.android.documentsui.testing.TestProvidersAccess;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class GlobalSearchLoaderTest {
+
+    private static final String SEARCH_STRING = "freddy";
+    private static int FILE_FLAG = Document.FLAG_SUPPORTS_MOVE | Document.FLAG_SUPPORTS_DELETE
+            | Document.FLAG_SUPPORTS_REMOVE;
+
+    private TestEnv mEnv;
+    private TestActivity mActivity;
+    private GlobalSearchLoader mLoader;
+
+    @Before
+    public void setUp() {
+        mEnv = TestEnv.create();
+        mActivity = TestActivity.create(mEnv);
+        mActivity.activityManager = ActivityManagers.create(false);
+
+        mEnv.state.action = State.ACTION_BROWSE;
+        mEnv.state.acceptMimes = new String[]{"*/*"};
+
+        final Bundle queryArgs = new Bundle();
+        queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, SEARCH_STRING);
+        mLoader = new GlobalSearchLoader(mActivity, mEnv.providers, mEnv.state,
+                TestImmediateExecutor.createLookup(), new TestFileTypeLookup(), queryArgs);
+
+        final DocumentInfo doc = mEnv.model.createFile(SEARCH_STRING + ".jpg", FILE_FLAG);
+        doc.lastModified = System.currentTimeMillis();
+        mEnv.mockProviders.get(TestProvidersAccess.HOME.authority)
+                .setNextChildDocumentsReturns(doc);
+
+        TestProvidersAccess.HOME.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+        mEnv.state.showAdvanced = true;
+    }
+
+    @After
+    public void tearDown() {
+        TestProvidersAccess.HOME.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+        mEnv.state.showAdvanced = false;
+    }
+
+    @Test
+    public void testNotSearchableRoot_beIgnored() {
+        TestProvidersAccess.PICKLES.flags |= DocumentsContract.Root.FLAG_LOCAL_ONLY;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.PICKLES));
+        TestProvidersAccess.PICKLES.flags &= ~DocumentsContract.Root.FLAG_LOCAL_ONLY;
+    }
+
+    @Test
+    public void testNotLocalOnlyRoot_beIgnored() {
+        TestProvidersAccess.PICKLES.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.PICKLES));
+        TestProvidersAccess.PICKLES.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+    }
+
+    @Test
+    public void testShowAdvance_recentRoot_beIgnored() {
+        TestProvidersAccess.IMAGE.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.IMAGE));
+        TestProvidersAccess.IMAGE.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+    }
+
+    @Test
+    public void testShowAdvance_imageRoot_beIgnored() {
+        TestProvidersAccess.IMAGE.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
+                | DocumentsContract.Root.FLAG_LOCAL_ONLY;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.IMAGE));
+        TestProvidersAccess.IMAGE.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
+                | DocumentsContract.Root.FLAG_LOCAL_ONLY);
+    }
+
+    @Test
+    public void testShowAdvance_videoRoot_beIgnored() {
+        TestProvidersAccess.VIDEO.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
+                | DocumentsContract.Root.FLAG_LOCAL_ONLY;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.VIDEO));
+        TestProvidersAccess.VIDEO.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
+                | DocumentsContract.Root.FLAG_LOCAL_ONLY);
+    }
+
+    @Test
+    public void testShowAdvance_audioRoot_beIgnored() {
+        TestProvidersAccess.AUDIO.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
+                | DocumentsContract.Root.FLAG_LOCAL_ONLY;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.AUDIO));
+        TestProvidersAccess.AUDIO.flags &= ~(DocumentsContract.Root.FLAG_SUPPORTS_SEARCH
+                | DocumentsContract.Root.FLAG_LOCAL_ONLY);
+    }
+
+    @Test
+    public void testShowAdvance_downloadRoot_beIgnored() {
+        TestProvidersAccess.DOWNLOADS.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.DOWNLOADS));
+        TestProvidersAccess.DOWNLOADS.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+    }
+
+    @Test
+    public void testSearchResult_includeDirectory() {
+        final DocumentInfo doc = mEnv.model.createFolder(SEARCH_STRING);
+        doc.lastModified = System.currentTimeMillis();
+
+        mEnv.mockProviders.get(TestProvidersAccess.HOME.authority)
+                .setNextChildDocumentsReturns(doc);
+
+        final DirectoryResult result = mLoader.loadInBackground();
+
+        final Cursor c = result.cursor;
+        assertEquals(1, c.getCount());
+
+        c.moveToNext();
+        final String mimeType = c.getString(c.getColumnIndex(Document.COLUMN_MIME_TYPE));
+        assertEquals(Document.MIME_TYPE_DIR, mimeType);
+    }
+
+    @Test
+    public void testSearchResult_isNotMovable() {
+        final DirectoryResult result = mLoader.loadInBackground();
+
+        final Cursor c = result.cursor;
+        assertEquals(1, c.getCount());
+
+        c.moveToNext();
+        final int flags = c.getInt(c.getColumnIndex(Document.COLUMN_FLAGS));
+        assertEquals(0, flags & Document.FLAG_SUPPORTS_DELETE);
+        assertEquals(0, flags & Document.FLAG_SUPPORTS_REMOVE);
+        assertEquals(0, flags & Document.FLAG_SUPPORTS_MOVE);
+    }
+
+    @Test
+    public void testSearchResult_includeSearchString() {
+        final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
+        pdfDoc.lastModified = System.currentTimeMillis();
+
+        final DocumentInfo apkDoc = mEnv.model.createFile(SEARCH_STRING + ".apk");
+        apkDoc.lastModified = System.currentTimeMillis();
+
+        final DocumentInfo testApkDoc = mEnv.model.createFile("test.apk");
+        testApkDoc.lastModified = System.currentTimeMillis();
+
+        mEnv.mockProviders.get(TestProvidersAccess.HOME.authority)
+                .setNextChildDocumentsReturns(pdfDoc, apkDoc, testApkDoc);
+
+        mEnv.state.sortModel.sortByUser(
+                SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
+
+        final DirectoryResult result = mLoader.loadInBackground();
+        final Cursor c = result.cursor;
+
+        assertEquals(2, c.getCount());
+
+        c.moveToNext();
+        String displayName = c.getString(c.getColumnIndex(Document.COLUMN_DISPLAY_NAME));
+        assertTrue(displayName.contains(SEARCH_STRING));
+
+        c.moveToNext();
+        displayName = c.getString(c.getColumnIndex(Document.COLUMN_DISPLAY_NAME));
+        assertTrue(displayName.contains(SEARCH_STRING));
+    }
+
+    @Test
+    public void testSearchResult_includeDifferentRoot() {
+        final DocumentInfo pdfDoc = mEnv.model.createFile(SEARCH_STRING + ".pdf");
+        pdfDoc.lastModified = System.currentTimeMillis();
+
+        final DocumentInfo apkDoc = mEnv.model.createFile(SEARCH_STRING + ".apk");
+        apkDoc.lastModified = System.currentTimeMillis();
+
+        final DocumentInfo testApkDoc = mEnv.model.createFile("test.apk");
+        testApkDoc.lastModified = System.currentTimeMillis();
+
+        mEnv.mockProviders.get(TestProvidersAccess.HAMMY.authority)
+                .setNextChildDocumentsReturns(pdfDoc, apkDoc, testApkDoc);
+
+        TestProvidersAccess.HAMMY.flags |= DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+
+        mEnv.state.sortModel.sortByUser(
+                SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING);
+
+        final DirectoryResult result = mLoader.loadInBackground();
+        final Cursor c = result.cursor;
+
+        assertEquals(3, c.getCount());
+
+        TestProvidersAccess.HAMMY.flags &= ~DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/IconUtilsTest.java b/tests/unit/com/android/documentsui/IconUtilsTest.java
new file mode 100644
index 0000000..f5547bd
--- /dev/null
+++ b/tests/unit/com/android/documentsui/IconUtilsTest.java
@@ -0,0 +1,58 @@
+package com.android.documentsui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class IconUtilsTest {
+    private static final String AUDIO_MIME_TYPE = "audio";
+    private static final String IMAGE_MIME_TYPE = "image";
+    private static final String TEXT_MIME_TYPE = "text";
+    private static final String VIDEO_MIME_TYPE = "video";
+    private static final String GENERIC_MIME_TYPE = "generic";
+
+    private Context mTargetContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mTargetContext = InstrumentationRegistry.getTargetContext();
+    }
+
+    @Test
+    public void testLoadMimeIcon_isAudioMimeType() {
+        assertThat(IconUtils.loadMimeIcon(mTargetContext, AUDIO_MIME_TYPE)).isNotNull();
+    }
+
+    @Test
+    public void testLoadMimeIcon_isImageMimeType() {
+        assertThat(IconUtils.loadMimeIcon(mTargetContext, IMAGE_MIME_TYPE)).isNotNull();
+    }
+
+    @Test
+    public void testLoadMimeIcon_isGenericMimeType() {
+        assertThat(IconUtils.loadMimeIcon(mTargetContext, GENERIC_MIME_TYPE)).isNotNull();
+    }
+
+    @Test
+    public void testLoadMimeIcon_isVideoMimeType() {
+        assertThat(IconUtils.loadMimeIcon(mTargetContext, VIDEO_MIME_TYPE)).isNotNull();
+    }
+
+    @Test
+    public void testLoadMimeIcon_isTextMimeType() {
+        assertThat(IconUtils.loadMimeIcon(mTargetContext, TEXT_MIME_TYPE)).isNotNull();
+    }
+
+    @Test
+    public void testLoadMimeIcon_isMimeTypeNull_shouldReturnNull() {
+        assertThat(IconUtils.loadMimeIcon(mTargetContext, null)).isNull();
+    }
+}
diff --git a/tests/unit/com/android/documentsui/ItemDragListenerTest.java b/tests/unit/com/android/documentsui/ItemDragListenerTest.java
index c083f9f..94a867a 100644
--- a/tests/unit/com/android/documentsui/ItemDragListenerTest.java
+++ b/tests/unit/com/android/documentsui/ItemDragListenerTest.java
@@ -18,17 +18,17 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import android.content.ClipData;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.DragEvent;
 import android.view.View;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.testing.ClipDatas;
 import com.android.documentsui.testing.DragEvents;
 import com.android.documentsui.testing.TestDrawable;
@@ -161,6 +161,18 @@
     }
 
     @Test
+    public void testDoNotHandleDragEvent() {
+        mTestDragHost.mLastEnteredView = null;
+
+        mTestDragHost.mCanHandleDragEvent = false;
+        final boolean handled = triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+        mTestDragHost.mCanHandleDragEvent = true;
+
+        assertFalse(handled);
+        assertNull(mTestDragHost.mLastEnteredView);
+    }
+
+    @Test
     public void testNoDropWithoutClipData() {
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
 
@@ -218,6 +230,13 @@
         private View mLastEnteredView;
         private View mLastExitedView;
 
+        private boolean mCanHandleDragEvent = true;
+
+        @Override
+        public boolean canHandleDragEvent(View v) {
+            return mCanHandleDragEvent;
+        }
+
         @Override
         public void setDropTargetHighlight(View v, boolean highlight) {
             mHighlightedView = highlight ? v : null;
diff --git a/tests/unit/com/android/documentsui/MetricsTest.java b/tests/unit/com/android/documentsui/MetricsTest.java
new file mode 100644
index 0000000..cdf67a9
--- /dev/null
+++ b/tests/unit/com/android/documentsui/MetricsTest.java
@@ -0,0 +1,39 @@
+package com.android.documentsui;
+
+import android.content.Intent;
+import android.net.Uri;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.base.Providers;
+import com.android.documentsui.base.State;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the specialized behaviors provided by Metrics.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MetricsTest {
+    @Test
+    public void logActivityLaunch_storageAuthority_shouldNotCrash() {
+        final Intent intent = new Intent(null, Uri.parse(
+                "content://" + Providers.AUTHORITY_STORAGE + "/document/primary:"));
+        final State state = new State();
+        state.action = State.ACTION_BROWSE;
+        Metrics.logActivityLaunch(state, intent);
+    }
+
+    @Test
+    public void logActivityLaunch_mediaAuthority_shouldNotCrash() {
+        final Intent intent = new Intent(null, Uri.parse(
+                "content://" + Providers.AUTHORITY_MEDIA + "/document/primary:"));
+        final State state = new State();
+        state.action = State.ACTION_BROWSE;
+        Metrics.logActivityLaunch(state, intent);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/ModelTest.java b/tests/unit/com/android/documentsui/ModelTest.java
index 8d3a33b..7d44477 100644
--- a/tests/unit/com/android/documentsui/ModelTest.java
+++ b/tests/unit/com/android/documentsui/ModelTest.java
@@ -23,8 +23,9 @@
 import android.database.MatrixCursor;
 import android.database.MergeCursor;
 import android.provider.DocumentsContract.Document;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.roots.RootCursorWrapper;
diff --git a/tests/unit/com/android/documentsui/RecentsLoaderTests.java b/tests/unit/com/android/documentsui/RecentsLoaderTests.java
index 657432f..f044b92 100644
--- a/tests/unit/com/android/documentsui/RecentsLoaderTests.java
+++ b/tests/unit/com/android/documentsui/RecentsLoaderTests.java
@@ -17,18 +17,19 @@
 package com.android.documentsui;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
 import android.database.Cursor;
 import android.provider.DocumentsContract.Document;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.State;
 import com.android.documentsui.testing.ActivityManagers;
 import com.android.documentsui.testing.TestEnv;
-import com.android.documentsui.testing.TestFeatures;
 import com.android.documentsui.testing.TestFileTypeLookup;
 import com.android.documentsui.testing.TestImmediateExecutor;
 import com.android.documentsui.testing.TestProvidersAccess;
@@ -54,11 +55,35 @@
         mEnv.state.action = State.ACTION_BROWSE;
         mEnv.state.acceptMimes = new String[] { "*/*" };
 
-        mLoader = new RecentsLoader(mActivity, mEnv.providers, mEnv.state, mEnv.features,
+        mLoader = new RecentsLoader(mActivity, mEnv.providers, mEnv.state,
                 TestImmediateExecutor.createLookup(), new TestFileTypeLookup());
     }
 
     @Test
+    public void testNotLocalOnlyRoot_beIgnored() {
+        assertTrue(mLoader.shouldIgnoreRoot(TestProvidersAccess.PICKLES));
+    }
+
+    @Test
+    public void testLocalOnlyRoot_supportRecent_notIgnored() {
+        assertFalse(mLoader.shouldIgnoreRoot(TestProvidersAccess.DOWNLOADS));
+    }
+
+    @Test
+    public void testDocumentsNotIncludeDirectory() {
+        final DocumentInfo doc = mEnv.model.createFolder("test");
+        doc.lastModified = System.currentTimeMillis();
+
+        mEnv.mockProviders.get(TestProvidersAccess.HOME.authority)
+                .setNextChildDocumentsReturns(doc);
+
+        final DirectoryResult result = mLoader.loadInBackground();
+
+        final Cursor c = result.cursor;
+        assertEquals(0, c.getCount());
+    }
+
+    @Test
     public void testDocumentsNotMovable() {
         final DocumentInfo doc = mEnv.model.createFile("freddy.jpg",
                 Document.FLAG_SUPPORTS_MOVE
diff --git a/tests/unit/com/android/documentsui/SharedInputHandlerTest.java b/tests/unit/com/android/documentsui/SharedInputHandlerTest.java
index 9c28094..d774b85 100644
--- a/tests/unit/com/android/documentsui/SharedInputHandlerTest.java
+++ b/tests/unit/com/android/documentsui/SharedInputHandlerTest.java
@@ -20,15 +20,16 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.base.Procedure;
 import com.android.documentsui.dirlist.TestFocusHandler;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.testing.SelectionHelpers;
+import com.android.documentsui.testing.TestDrawerController;
 import com.android.documentsui.testing.TestFeatures;
 
 import org.junit.Before;
@@ -40,9 +41,10 @@
 public class SharedInputHandlerTest {
 
     private SharedInputHandler mSharedInputHandler;
-    private SelectionHelper mSelectionMgr = SelectionHelpers.createTestInstance();
+    private SelectionTracker<String> mSelectionMgr = SelectionHelpers.createTestInstance();
     private TestFeatures mFeatures = new TestFeatures();
     private TestFocusHandler mFocusHandler = new TestFocusHandler();
+    private TestDrawerController mDrawer = TestDrawerController.create();
     private boolean mDirPopHappened;
     private boolean mCanceledSearch;
     private Procedure mDirPopper = new Procedure() {
@@ -63,7 +65,8 @@
                     return false;
                 },
                 mDirPopper,
-                mFeatures);
+                mFeatures,
+                mDrawer);
     }
 
     @Test
@@ -84,7 +87,8 @@
                         return true;
                 },
                 mDirPopper,
-                new TestFeatures());
+                new TestFeatures(),
+                mDrawer);
         KeyEvent backEvent =
                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
         assertTrue(mSharedInputHandler.onKeyDown(backEvent.getKeyCode(), backEvent));
@@ -92,6 +96,7 @@
         assertTrue(mCanceledSearch);
         assertEquals(mSelectionMgr.getSelection().size(), 1);
         assertFalse(mDirPopHappened);
+        mDrawer.assertWasClosed();
     }
 
     @Test
@@ -105,6 +110,7 @@
         assertFalse(mCanceledSearch);
         assertEquals(mSelectionMgr.getSelection().size(), 0);
         assertFalse(mDirPopHappened);
+        mDrawer.assertWasClosed();
     }
 
     @Test
@@ -116,6 +122,16 @@
         assertFalse(mCanceledSearch);
         assertEquals(mSelectionMgr.getSelection().size(), 0);
         assertTrue(mDirPopHappened);
+        mDrawer.assertWasClosed();
+    }
+
+    @Test
+    public void testBackButton_CloseDrawer() {
+        KeyEvent backEvent =
+                new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
+        mDrawer.openDrawer(true);
+        assertTrue(mSharedInputHandler.onKeyDown(backEvent.getKeyCode(), backEvent));
+        mDrawer.assertWasOpened();
     }
 
     @Test
@@ -129,7 +145,8 @@
                         return true;
                 },
                 mDirPopper,
-                new TestFeatures());
+                new TestFeatures(),
+                mDrawer);
         KeyEvent escapeEvent =
                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ESCAPE, 0, 0);
         assertTrue(mSharedInputHandler.onKeyDown(escapeEvent.getKeyCode(), escapeEvent));
diff --git a/tests/unit/com/android/documentsui/ThumbnailCacheTest.java b/tests/unit/com/android/documentsui/ThumbnailCacheTest.java
index ee6ab01..570cefc 100644
--- a/tests/unit/com/android/documentsui/ThumbnailCacheTest.java
+++ b/tests/unit/com/android/documentsui/ThumbnailCacheTest.java
@@ -25,8 +25,9 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.net.Uri;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.ThumbnailCache.Result;
 import com.android.documentsui.testing.Bitmaps;
diff --git a/tests/unit/com/android/documentsui/selection/ViewAutoScrollerTest.java b/tests/unit/com/android/documentsui/ViewAutoScrollerTest.java
similarity index 92%
rename from tests/unit/com/android/documentsui/selection/ViewAutoScrollerTest.java
rename to tests/unit/com/android/documentsui/ViewAutoScrollerTest.java
index b75c3da..44ebadd 100644
--- a/tests/unit/com/android/documentsui/selection/ViewAutoScrollerTest.java
+++ b/tests/unit/com/android/documentsui/ViewAutoScrollerTest.java
@@ -14,17 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.documentsui.selection;
+package com.android.documentsui;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.graphics.Point;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 
-import com.android.documentsui.selection.ViewAutoScroller.ScrollHost;
-import com.android.documentsui.selection.ViewAutoScroller.ScrollerCallbacks;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.ViewAutoScroller;
+import com.android.documentsui.ViewAutoScroller.ScrollHost;
+import com.android.documentsui.ViewAutoScroller.ScrollerCallbacks;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/unit/com/android/documentsui/archives/ArchiveFileTestRule.java b/tests/unit/com/android/documentsui/archives/ArchiveFileTestRule.java
new file mode 100644
index 0000000..f3ef5ba
--- /dev/null
+++ b/tests/unit/com/android/documentsui/archives/ArchiveFileTestRule.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2019 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.documentsui.archives;
+
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import org.apache.commons.compress.utils.IOUtils;
+import org.junit.rules.TestName;
+import org.junit.runner.Description;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+
+public class ArchiveFileTestRule extends TestName {
+    private static final String TAG = ArchiveFileTestRule.class.getSimpleName();
+
+    private final List<Path> mTemporaries;
+    private final List<ParcelFileDescriptor> mParcelFileDescriptors;
+
+    private String mClassName;
+    private String mMethodName;
+    private Path mTemporaryPath;
+
+    public ArchiveFileTestRule() {
+        mTemporaries = new ArrayList<>();
+        mParcelFileDescriptors = new ArrayList<>();
+    }
+
+    @Override
+    protected void starting(Description description) {
+        super.starting(description);
+        mClassName = description.getClassName();
+        mMethodName = description.getMethodName();
+
+        try {
+            mTemporaryPath = Files.createTempDirectory(
+                    InstrumentationRegistry.getInstrumentation()
+                            .getTargetContext().getCacheDir().toPath(),
+                    mClassName);
+        } catch (IOException e) {
+            Log.e(TAG, String.format(Locale.ENGLISH,
+                    "It can't create temporary directory in the staring of %s.%s.",
+                    mClassName, mMethodName));
+        }
+    }
+
+    @Override
+    protected void finished(Description description) {
+        super.finished(description);
+
+        for (Path path : mTemporaries) {
+            if (path != null) {
+                path.toFile().delete();
+            }
+        }
+
+        mTemporaryPath.toFile().delete();
+
+        for (ParcelFileDescriptor parcelFileDescriptor : mParcelFileDescriptors) {
+            IOUtils.closeQuietly(parcelFileDescriptor);
+        }
+    }
+
+    /**
+     * To generate the temporary file and return the file path.
+     *
+     * @param suffix the suffix of the temporary file name
+     * @return the file path
+     * @throws IOException to create temporary file fail raises IOException
+     */
+    public Path generateFile(String suffix) throws IOException {
+        Set<PosixFilePermission> perm = PosixFilePermissions.fromString("rwx------");
+        FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perm);
+        Path filePath = Files.createTempFile(mTemporaryPath, mMethodName, suffix, attr);
+        mTemporaries.add(filePath);
+        return filePath;
+    }
+
+    /**
+     * To dump asset path file as temporary file. There are some problems to get the file
+     * descriptor from the asset files in instrumentation context. It's null pointer. It needs to
+     * dump to temporary file in the target context of the instrumentation.
+     *
+     * @param assetPath assetPath in test context
+     * @param suffix the suffix of the temporary file name
+     * @return the file path
+     */
+    public Path dumpAssetFile(String assetPath, String suffix) throws IOException {
+        Path destinationPath = generateFile(suffix);
+
+        try (InputStream inputStream = InstrumentationRegistry.getInstrumentation()
+                .getContext().getAssets().open(assetPath)) {
+            Files.copy(inputStream, destinationPath, StandardCopyOption.REPLACE_EXISTING);
+        }
+
+        return destinationPath;
+    }
+
+    /**
+     * To dump asset path file as temporary file. There are some problems to get the file
+     * descriptor from the asset files in instrumentation context. It's null pointer. It needs to
+     * dump to temporary file in the target context of the instrumentation.
+     *
+     * @param assetPath assetPath in test context
+     * @param suffix the suffix of the temporary file name
+     * @return the file path
+     */
+    public ParcelFileDescriptor openAssetFile(String assetPath, String suffix) throws IOException {
+        Path destinationPath = dumpAssetFile(assetPath, suffix);
+
+        ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor
+                .open(destinationPath.toFile(), MODE_READ_ONLY);
+
+        mParcelFileDescriptors.add(parcelFileDescriptor);
+        return parcelFileDescriptor;
+    }
+
+    /**
+     * To get asset content that is a type of text.
+     *
+     * @param assetPath assetPath in test context
+     * @return the text content
+     */
+    public String getAssetText(String assetPath) throws IOException {
+        ParcelFileDescriptor parcelFileDescriptor = openAssetFile(assetPath, ".text");
+
+        try (FileInputStream fileInputStream =
+                     new FileInputStream(parcelFileDescriptor.getFileDescriptor())){
+            return getStringFromInputStream(fileInputStream);
+        }
+    }
+
+    public static String getStringFromInputStream(InputStream inputStream) throws IOException {
+        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+
+        int size = inputStream.available();
+        char[] buffer = new char[size];
+
+        inputStreamReader.read(buffer);
+
+        return new String(buffer);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/archives/ArchiveHandleTest.java b/tests/unit/com/android/documentsui/archives/ArchiveHandleTest.java
new file mode 100644
index 0000000..d962f91
--- /dev/null
+++ b/tests/unit/com/android/documentsui/archives/ArchiveHandleTest.java
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2019 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.documentsui.archives;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.os.ParcelFileDescriptor;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.runner.AndroidJUnit4;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class ArchiveHandleTest {
+    @Rule
+    public ArchiveFileTestRule mArchiveFileTestRule = new ArchiveFileTestRule();
+
+
+    private ArchiveHandle prepareArchiveHandle(String archivePath, String suffix,
+            String mimeType) throws IOException, CompressorException, ArchiveException {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile(archivePath, suffix);
+
+        return ArchiveHandle.create(parcelFileDescriptor, mimeType);
+    }
+
+    private static ArchiveEntry getFileInArchive(Enumeration<ArchiveEntry> enumeration,
+            String pathInArchive) {
+        while (enumeration.hasMoreElements()) {
+            ArchiveEntry entry = enumeration.nextElement();
+            if (entry.getName().equals(pathInArchive)) {
+                return entry;
+            }
+        }
+        return null;
+    }
+
+
+    private static class ArchiveEntryRecord implements ArchiveEntry {
+        private final String mName;
+        private final long mSize;
+        private final boolean mIsDirectory;
+
+        private ArchiveEntryRecord(ArchiveEntry archiveEntry) {
+            this(archiveEntry.getName(), archiveEntry.getSize(), archiveEntry.isDirectory());
+        }
+
+        private ArchiveEntryRecord(String name, long size, boolean isDirectory) {
+            mName = name;
+            mSize = size;
+            mIsDirectory = isDirectory;
+        }
+
+        @Override
+        public boolean equals(@Nullable Object obj) {
+            if (obj == null) {
+                return false;
+            }
+
+            if (obj instanceof ArchiveEntryRecord) {
+                ArchiveEntryRecord recordB = (ArchiveEntryRecord) obj;
+                return mName.equals(recordB.mName)
+                        && mSize == recordB.mSize
+                        && mIsDirectory == recordB.mIsDirectory;
+            }
+
+            return false;
+        }
+
+        @Override
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public long getSize() {
+            return mSize;
+        }
+
+        @Override
+        public boolean isDirectory() {
+            return mIsDirectory;
+        }
+
+        @Override
+        public Date getLastModifiedDate() {
+            return null;
+        }
+
+        @NonNull
+        @Override
+        public String toString() {
+            return String.format(Locale.ENGLISH, "name: %s, size: %d, isDirectory: %b",
+                    mName, mSize, mIsDirectory);
+        }
+    }
+
+    private static List<ArchiveEntry> transformToIterable(Enumeration<ArchiveEntry> enumeration) {
+        List list = new ArrayList<ArchiveEntry>();
+        while (enumeration.hasMoreElements()) {
+            list.add(new ArchiveEntryRecord(enumeration.nextElement()));
+        }
+        return list;
+    }
+
+    private static final List<ArchiveEntryRecord> sExpectEntries =
+            new ArrayList<ArchiveEntryRecord>() {
+        {
+            add(new ArchiveEntryRecord("hello/hello.txt", 48, false));
+            add(new ArchiveEntryRecord("hello/inside_folder/hello_insside.txt",
+                            14, false));
+            add(new ArchiveEntryRecord("hello/hello2.txt", 48, false));
+        }
+    };
+
+
+    @Test
+    public void buildArchiveHandle_withoutFileDescriptor_shouldBeIllegal() throws Exception {
+        try {
+            ArchiveHandle.create(null,
+                    "application/x-7z-compressed");
+            fail("It should not be here!");
+        } catch (NullPointerException e) {
+            /* do nothing */
+        }
+    }
+
+    @Test
+    public void buildArchiveHandle_withWrongMimeType_shouldBeIllegal() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/7z/hello.7z", ".7z");
+
+        try {
+            ArchiveHandle.create(parcelFileDescriptor, null);
+            fail("It should not be here!");
+        } catch (IllegalArgumentException e) {
+            /* do nothing */
+        }
+    }
+
+    @Test
+    public void buildArchiveHandle_sevenZFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/7z/hello.7z",
+                ".7z", "application/x-7z-compressed");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_zipFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_zipWithWrongMimeType_shouldBeNull() throws Exception {
+        try {
+            prepareArchiveHandle("archives/zip/hello.zip",
+                    ".zip", "application/xxxzip");
+            fail("It should not be here!");
+        } catch (UnsupportedOperationException e) {
+            /* do nothing */
+        }
+    }
+
+    @Test
+    public void buildArchiveHandle_tarFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/tar/hello.tar",
+                ".tar","application/x-gtar");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_tgzFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/tar_gz/hello.tgz",
+                ".tgz", "application/x-compressed-tar");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_tarGzFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/tar_gz/hello_tar_gz", ".tar.gz",
+                        "application/x-compressed-tar");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_tarBzipFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/tar_bz2/hello.tar.bz2",
+                        ".tar.bz2", "application/x-bzip-compressed-tar");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_tarXzFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/xz/hello.tar.xz", ".tar.xz",
+                        "application/x-xz-compressed-tar");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void buildArchiveHandle_tarBrFile_shouldNotNull() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/brotli/hello.tar.br", ".tar.br",
+                "application/x-brotli-compressed-tar");
+
+        assertThat(archiveHandle).isNotNull();
+    }
+
+    @Test
+    public void getMimeType_sevenZFile_shouldBeSevenZ()
+            throws CompressorException, ArchiveException, IOException {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/7z/hello.7z",
+                ".7z", "application/x-7z-compressed");
+
+        assertThat(archiveHandle.getMimeType()).isEqualTo("application/x-7z-compressed");
+    }
+
+    @Test
+    public void getMimeType_tarBrotli_shouldBeBrotliCompressedTar()
+            throws CompressorException, ArchiveException, IOException {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/brotli/hello.tar.br", ".tar.br",
+                        "application/x-brotli-compressed-tar");
+
+        assertThat(archiveHandle.getMimeType())
+                .isEqualTo("application/x-brotli-compressed-tar");
+    }
+
+    @Test
+    public void getMimeType_tarXz_shouldBeXzCompressedTar()
+            throws CompressorException, ArchiveException, IOException {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/xz/hello.tar.xz", ".tar.xz",
+                        "application/x-xz-compressed-tar");
+
+        assertThat(archiveHandle.getMimeType())
+                .isEqualTo("application/x-xz-compressed-tar");
+    }
+
+    @Test
+    public void getMimeType_tarGz_shouldBeCompressedTar()
+            throws CompressorException, ArchiveException, IOException {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/tar_gz/hello_tar_gz", ".tar.gz",
+                        "application/x-compressed-tar");
+
+        assertThat(archiveHandle.getMimeType())
+                .isEqualTo("application/x-compressed-tar");
+    }
+
+    @Test
+    public void getCommonArchive_tarBrFile_shouldBeCommonArchiveInputHandle() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/brotli/hello.tar.br", ".tar.br",
+                        "application/x-brotli-compressed-tar");
+
+        assertThat(archiveHandle.toString()).contains("CommonArchiveInputHandle");
+    }
+
+    @Test
+    public void getCommonArchive_sevenZFile_shouldBeSevenZFileHandle() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/7z/hello.7z",
+                ".7z", "application/x-7z-compressed");
+
+        assertThat(archiveHandle.toString()).contains("SevenZFileHandle");
+    }
+
+
+    @Test
+    public void getCommonArchive_zipFile_shouldBeZipFileHandle() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        assertThat(archiveHandle.toString()).contains("ZipFileHandle");
+    }
+
+    @Test
+    public void close_zipFile_shouldBeSuccess() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        archiveHandle.close();
+    }
+
+    @Test
+    public void close_sevenZFile_shouldBeSuccess() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/7z/hello.7z",
+                ".7z", "application/x-7z-compressed");
+
+        archiveHandle.close();
+    }
+
+    @Test
+    public void closeInputStream_zipFile_shouldBeSuccess() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        InputStream inputStream = archiveHandle.getInputStream(
+                getFileInArchive(archiveHandle.getEntries(),
+                        "hello/inside_folder/hello_insside.txt"));
+
+        assertThat(inputStream).isNotNull();
+
+        inputStream.close();
+    }
+
+    @Test
+    public void close_zipFile_shouldNotOpen() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor =  mArchiveFileTestRule
+                .openAssetFile("archives/zip/hello.zip", ".zip");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/zip");
+
+        archiveHandle.close();
+
+        FileInputStream fileInputStream =
+                new FileInputStream(parcelFileDescriptor.getFileDescriptor());
+        assertThat(fileInputStream).isNotNull();
+    }
+
+    @Test
+    public void getInputStream_zipFile_shouldHaveTheSameContent() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/zip/hello.zip", ".zip");
+
+        String expectedContent = mArchiveFileTestRule.getAssetText(
+                "archives/original/hello/inside_folder/hello_insside.txt");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/zip");
+
+        InputStream inputStream = archiveHandle.getInputStream(
+                getFileInArchive(archiveHandle.getEntries(),
+                        "hello/inside_folder/hello_insside.txt"));
+
+        assertThat(ArchiveFileTestRule.getStringFromInputStream(inputStream))
+                .isEqualTo(expectedContent);
+    }
+
+    @Test
+    public void getInputStream_zipFileNotExistEntry_shouldFail() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        ArchiveEntry archiveEntry = mock(ArchiveEntry.class);
+        when(archiveEntry.getName()).thenReturn("/not_exist_entry");
+
+        try {
+            archiveHandle.getInputStream(archiveEntry);
+            fail("It should not be here.");
+        } catch (IllegalArgumentException | ArchiveException | CompressorException e) {
+            /* do nothing */
+        }
+    }
+
+    @Test
+    public void getInputStream_directoryEntry_shouldFail() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        ArchiveEntry archiveEntry = mock(ArchiveEntry.class);
+        when(archiveEntry.isDirectory()).thenReturn(true);
+
+        try {
+            archiveHandle.getInputStream(archiveEntry);
+            fail("It should not be here.");
+        } catch (IllegalArgumentException e) {
+            /* expected, do nothing */
+        }
+    }
+
+    @Test
+    public void getInputStream_zeroSizeEntry_shouldFail() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        ArchiveEntry archiveEntry = mock(ArchiveEntry.class);
+        when(archiveEntry.isDirectory()).thenReturn(false);
+        when(archiveEntry.getSize()).thenReturn(0L);
+
+        try {
+            archiveHandle.getInputStream(archiveEntry);
+            fail("It should not be here.");
+        } catch (IllegalArgumentException e) {
+            /* expected, do nothing */
+        }
+    }
+
+    @Test
+    public void getInputStream_emptyStringEntry_shouldFail() throws Exception {
+        ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip",
+                ".zip", "application/zip");
+
+        ArchiveEntry archiveEntry = mock(ArchiveEntry.class);
+        when(archiveEntry.isDirectory()).thenReturn(false);
+        when(archiveEntry.getSize()).thenReturn(14L);
+        when(archiveEntry.getName()).thenReturn("");
+
+        try {
+            archiveHandle.getInputStream(archiveEntry);
+            fail("It should not be here.");
+        } catch (IllegalArgumentException e) {
+            /* expected, do nothing */
+        }
+    }
+
+    @Test
+    public void getInputStream_sevenZFile_shouldHaveTheSameContent() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/7z/hello.7z", ".7z");
+
+        String expectedContent = mArchiveFileTestRule.getAssetText(
+                "archives/original/hello/inside_folder/hello_insside.txt");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/x-7z-compressed");
+
+        InputStream inputStream = archiveHandle.getInputStream(
+                getFileInArchive(archiveHandle.getEntries(),
+                        "hello/inside_folder/hello_insside.txt"));
+
+        assertThat(ArchiveFileTestRule.getStringFromInputStream(inputStream))
+                .isEqualTo(expectedContent);
+    }
+
+    @Test
+    public void getInputStream_tarGzFile_shouldHaveTheSameContent() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/tar_gz/hello.tgz", ".tar.gz");
+
+        String expectedContent = mArchiveFileTestRule.getAssetText(
+                "archives/original/hello/inside_folder/hello_insside.txt");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/x-compressed-tar");
+
+        InputStream inputStream = archiveHandle.getInputStream(
+                getFileInArchive(archiveHandle.getEntries(),
+                        "hello/inside_folder/hello_insside.txt"));
+
+        assertThat(ArchiveFileTestRule.getStringFromInputStream(inputStream))
+                .isEqualTo(expectedContent);
+    }
+
+    @Test
+    public void getInputStream_tarGzFileNullEntry_getNullInputStream() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/tar_gz/hello.tgz", ".tar.gz");
+
+        String expectedContent = mArchiveFileTestRule.getAssetText(
+                "archives/original/hello/inside_folder/hello_insside.txt");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/x-compressed-tar");
+
+        try {
+            archiveHandle.getInputStream(null);
+            fail("It should not here");
+        } catch (IllegalArgumentException | ArchiveException | CompressorException e) {
+            /* expected, do nothing */
+        }
+    }
+
+
+    @Test
+    public void getInputStream_tarGzFileInvalidEntry_getNullInputStream() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/tar_gz/hello.tgz", ".tar.gz");
+
+        String expectedContent = mArchiveFileTestRule.getAssetText(
+                "archives/original/hello/inside_folder/hello_insside.txt");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/x-compressed-tar");
+
+        ArchiveEntry archiveEntry = mock(ArchiveEntry.class);
+        when(archiveEntry.getName()).thenReturn("");
+        try {
+            archiveHandle.getInputStream(archiveEntry);
+            fail("It should not here");
+        } catch (IllegalArgumentException | ArchiveException | CompressorException e) {
+            /* expected, do nothing */
+        }
+    }
+
+    @Test
+    public void getInputStream_tarBrotliFile_shouldHaveTheSameContent() throws Exception {
+        ParcelFileDescriptor parcelFileDescriptor = mArchiveFileTestRule
+                .openAssetFile("archives/brotli/hello.tar.br", ".tar.br");
+
+        String expectedContent = mArchiveFileTestRule.getAssetText(
+                "archives/original/hello/inside_folder/hello_insside.txt");
+
+        ArchiveHandle archiveHandle = ArchiveHandle.create(parcelFileDescriptor,
+                "application/x-brotli-compressed-tar");
+
+        InputStream inputStream = archiveHandle.getInputStream(
+                getFileInArchive(archiveHandle.getEntries(),
+                        "hello/inside_folder/hello_insside.txt"));
+
+        assertThat(ArchiveFileTestRule.getStringFromInputStream(inputStream))
+                .isEqualTo(expectedContent);
+    }
+
+    @Test
+    public void getEntries_zipFile_shouldTheSameWithList() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/zip/hello.zip", ".zip",
+                        "application/zip");
+
+        assertThat(transformToIterable(archiveHandle.getEntries()))
+                .containsAllIn(sExpectEntries);
+    }
+
+    @Test
+    public void getEntries_tarFile_shouldTheSameWithList() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/tar/hello.tar", ".tar",
+                "application/x-gtar");
+
+        assertThat(transformToIterable(archiveHandle.getEntries()))
+                .containsAllIn(sExpectEntries);
+    }
+
+    @Test
+    public void getEntries_tgzFile_shouldTheSameWithList() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/tar_gz/hello.tgz", ".tgz",
+                        "application/x-compressed-tar");
+
+        assertThat(transformToIterable(archiveHandle.getEntries()))
+                .containsAllIn(sExpectEntries);
+    }
+
+    @Test
+    public void getEntries_tarBzFile_shouldTheSameWithList() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/tar_bz2/hello.tar.bz2", ".tar.bz2",
+                        "application/x-bzip-compressed-tar");
+
+        assertThat(transformToIterable(archiveHandle.getEntries()))
+                .containsAllIn(sExpectEntries);
+    }
+
+    @Test
+    public void getEntries_tarBrotliFile_shouldTheSameWithList() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/brotli/hello.tar.br", ".tar.br",
+                        "application/x-brotli-compressed-tar");
+
+        assertThat(transformToIterable(archiveHandle.getEntries()))
+                .containsAllIn(sExpectEntries);
+    }
+
+    @Test
+    public void getEntries_tarXzFile_shouldTheSameWithList() throws Exception {
+        ArchiveHandle archiveHandle =
+                prepareArchiveHandle("archives/xz/hello.tar.xz", ".tar.xz",
+                        "application/x-xz-compressed-tar");
+
+        assertThat(transformToIterable(archiveHandle.getEntries()))
+                .containsAllIn(sExpectEntries);
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java b/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
index cc40e56..4843425 100644
--- a/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
+++ b/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
@@ -16,6 +16,10 @@
 
 package com.android.documentsui.archives;
 
+import static android.content.ContentResolver.wrap;
+
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
@@ -31,24 +35,27 @@
 import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.text.TextUtils;
+import android.util.Log;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class ArchivesProviderTest {
@@ -265,10 +272,10 @@
         client.release();
     }
 
-    @Test
-    public void testGetDocumentMetadata() throws InterruptedException, RemoteException {
+    private void getDocumentMetadata_byDocumentId_shouldMatchSize(String documentId)
+            throws Exception {
         final Uri sourceUri = DocumentsContract.buildDocumentUri(
-                ResourcesProvider.AUTHORITY, "images.zip");
+                ResourcesProvider.AUTHORITY, documentId);
         final Uri archiveUri = ArchivesProvider.buildUriForArchive(sourceUri,
                 ParcelFileDescriptor.MODE_READ_ONLY);
 
@@ -280,19 +287,39 @@
 
         Uri archivedImageUri = Uri.parse(
                 "content://com.android.documentsui.archives/document/content%3A%2F%2F"
-                + "com.android.documentsui.archives.resourcesprovider%2F"
-                + "document%2Fimages.zip%23268435456%23%2Ffreddy.jpg");
+                        + "com.android.documentsui.archives.resourcesprovider%2F"
+                        + "document%2F" + documentId + "%23268435456%23%2Ffreddy.jpg");
 
-        Bundle metadata = DocumentsContract.getDocumentMetadata(client, archivedImageUri);
+        Bundle metadata = DocumentsContract.getDocumentMetadata(wrap(client), archivedImageUri);
         assertNotNull(metadata);
         Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
         assertNotNull(exif);
 
-        assertEquals(3036, exif.getInt(ExifInterface.TAG_IMAGE_WIDTH));
-        assertEquals(4048, exif.getInt(ExifInterface.TAG_IMAGE_LENGTH));
-        assertEquals("Pixel", exif.getString(ExifInterface.TAG_MODEL));
+        assertThat(exif.getInt(ExifInterface.TAG_IMAGE_WIDTH)).isEqualTo(3036);
+        assertThat(exif.getInt(ExifInterface.TAG_IMAGE_LENGTH)).isEqualTo(4048);
+        assertThat(exif.getString(ExifInterface.TAG_MODEL)).isEqualTo("Pixel");
 
         ArchivesProvider.releaseArchive(client, archiveUri);
-        client.release();
+        client.close();
+    }
+
+    @Test
+    public void testGetDocumentMetadata() throws Exception {
+        getDocumentMetadata_byDocumentId_shouldMatchSize("images.zip");
+    }
+
+    @Test
+    public void getDocumentMetadata_sevenZFile_shouldMatchSize() throws Exception {
+        getDocumentMetadata_byDocumentId_shouldMatchSize("images.7z");
+    }
+
+    @Test
+    public void getDocumentMetadata_tgz_shouldMatchSize() throws Exception {
+        getDocumentMetadata_byDocumentId_shouldMatchSize("images.tgz");
+    }
+
+    @Test
+    public void getDocumentMetadata_tar_shouldMatchSize() throws Exception {
+        getDocumentMetadata_byDocumentId_shouldMatchSize("images.tar");
     }
 }
diff --git a/tests/unit/com/android/documentsui/archives/ReadableArchiveTest.java b/tests/unit/com/android/documentsui/archives/ReadableArchiveTest.java
index 98e4f09..f6378e3 100644
--- a/tests/unit/com/android/documentsui/archives/ReadableArchiveTest.java
+++ b/tests/unit/com/android/documentsui/archives/ReadableArchiveTest.java
@@ -16,32 +16,44 @@
 
 package com.android.documentsui.archives;
 
-import com.android.documentsui.archives.ReadableArchive;
-import com.android.documentsui.tests.R;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.content.Context;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
 import android.provider.DocumentsContract.Document;
-import android.support.test.InstrumentationRegistry;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
+import android.text.TextUtils;
 
-import java.io.File;
-import java.io.FileOutputStream;
+import androidx.annotation.IdRes;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.tests.R;
+
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.Scanner;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.compressors.CompressorException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
 @MediumTest
-public class ReadableArchiveTest extends AndroidTestCase {
+public class ReadableArchiveTest {
     private static final Uri ARCHIVE_URI = Uri.parse("content://i/love/strawberries");
     private static final String NOTIFICATION_URI =
             "content://com.android.documentsui.archives/notification-uri";
@@ -49,46 +61,67 @@
     private Archive mArchive = null;
     private TestUtils mTestUtils = null;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         mExecutor = Executors.newSingleThreadExecutor();
         mTestUtils = new TestUtils(InstrumentationRegistry.getTargetContext(),
                 InstrumentationRegistry.getContext(), mExecutor);
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         mExecutor.shutdown();
         assertTrue(mExecutor.awaitTermination(3 /* timeout */, TimeUnit.SECONDS));
         if (mArchive != null) {
             mArchive.close();
         }
-        super.tearDown();
     }
 
     public static ArchiveId createArchiveId(String path) {
         return new ArchiveId(ARCHIVE_URI, ParcelFileDescriptor.MODE_READ_ONLY, path);
     }
 
-    public void loadArchive(ParcelFileDescriptor descriptor) throws IOException {
+    private void loadArchive(ParcelFileDescriptor descriptor, String mimeType)
+            throws IOException, CompressorException, ArchiveException {
         mArchive = ReadableArchive.createForParcelFileDescriptor(
                 InstrumentationRegistry.getTargetContext(),
                 descriptor,
                 ARCHIVE_URI,
+                mimeType,
                 ParcelFileDescriptor.MODE_READ_ONLY,
                 Uri.parse(NOTIFICATION_URI));
     }
 
-    public void testQueryChildDocument() throws IOException {
+    private void loadArchive(ParcelFileDescriptor descriptor)
+            throws IOException, CompressorException, ArchiveException {
+        loadArchive(descriptor, "application/zip");
+    }
+
+    private static void assertRowExist(Cursor cursor, String targetDocId) {
+        assertTrue(cursor.moveToFirst());
+
+        boolean found = false;
+        final int count = cursor.getCount();
+        for (int i = 0; i < count; i++) {
+            cursor.moveToPosition(i);
+            if (TextUtils.equals(targetDocId, cursor.getString(
+                    cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)))) {
+                found = true;
+                break;
+            }
+        }
+
+        assertTrue(targetDocId + " should be exists", found);
+    }
+
+    @Test
+    public void testQueryChildDocument()
+            throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.archive));
         final Cursor cursor = mArchive.queryChildDocuments(
                 createArchiveId("/").toDocumentId(), null, null);
 
-        assertTrue(cursor.moveToFirst());
-        assertEquals(
-                createArchiveId("/file1.txt").toDocumentId(),
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
+        assertRowExist(cursor, createArchiveId("/file1.txt").toDocumentId());
         assertEquals("file1.txt",
                 cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
         assertEquals("text/plain",
@@ -96,9 +129,7 @@
         assertEquals(13,
                 cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
 
-        assertTrue(cursor.moveToNext());
-        assertEquals(createArchiveId("/dir1/").toDocumentId(),
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
+        assertRowExist(cursor, createArchiveId("/dir1/").toDocumentId());
         assertEquals("dir1",
                 cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
         assertEquals(Document.MIME_TYPE_DIR,
@@ -106,10 +137,7 @@
         assertEquals(0,
                 cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
 
-        assertTrue(cursor.moveToNext());
-        assertEquals(
-                createArchiveId("/dir2/").toDocumentId(),
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
+        assertRowExist(cursor, createArchiveId("/dir2/").toDocumentId());
         assertEquals("dir2",
                 cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
         assertEquals(Document.MIME_TYPE_DIR,
@@ -117,7 +145,6 @@
         assertEquals(0,
                 cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
 
-        assertFalse(cursor.moveToNext());
 
         // Check if querying children works too.
         final Cursor childCursor = mArchive.queryChildDocuments(
@@ -138,7 +165,9 @@
                 childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
     }
 
-    public void testQueryChildDocument_NoDirs() throws IOException {
+    @Test
+    public void testQueryChildDocument_NoDirs()
+            throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.no_dirs));
         final Cursor cursor = mArchive.queryChildDocuments(
             createArchiveId("/").toDocumentId(), null, null);
@@ -185,7 +214,9 @@
         assertFalse(childCursor2.moveToNext());
     }
 
-    public void testQueryChildDocument_EmptyDirs() throws IOException {
+    @Test
+    public void testQueryChildDocument_EmptyDirs()
+            throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.empty_dirs));
         final Cursor cursor = mArchive.queryChildDocuments(
                 createArchiveId("/").toDocumentId(), null, null);
@@ -205,11 +236,7 @@
         final Cursor childCursor = mArchive.queryChildDocuments(
                 createArchiveId("/dir1/").toDocumentId(), null, null);
 
-        assertTrue(childCursor.moveToFirst());
-        assertEquals(
-                createArchiveId("/dir1/dir2/").toDocumentId(),
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DOCUMENT_ID)));
+        assertRowExist(childCursor, createArchiveId("/dir1/dir2/").toDocumentId());
         assertEquals("dir2",
                 childCursor.getString(childCursor.getColumnIndexOrThrow(
                         Document.COLUMN_DISPLAY_NAME)));
@@ -219,7 +246,7 @@
         assertEquals(0,
                 childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
 
-        assertTrue(childCursor.moveToNext());
+        assertRowExist(childCursor, createArchiveId("/dir1/dir3/").toDocumentId());
         assertEquals(
                 createArchiveId("/dir1/dir3/").toDocumentId(),
                 childCursor.getString(childCursor.getColumnIndexOrThrow(
@@ -232,7 +259,6 @@
                         Document.COLUMN_MIME_TYPE)));
         assertEquals(0,
                 childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-        assertFalse(cursor.moveToNext());
 
         final Cursor childCursor2 = mArchive.queryChildDocuments(
                 createArchiveId("/dir1/dir2/").toDocumentId(),
@@ -245,7 +271,8 @@
         assertFalse(childCursor3.moveToFirst());
     }
 
-    public void testGetDocumentType() throws IOException {
+    @Test
+    public void testGetDocumentType() throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.archive));
         assertEquals(Document.MIME_TYPE_DIR, mArchive.getDocumentType(
                 createArchiveId("/dir1/").toDocumentId()));
@@ -253,7 +280,8 @@
                 createArchiveId("/file1.txt").toDocumentId()));
     }
 
-    public void testIsChildDocument() throws IOException {
+    @Test
+    public void testIsChildDocument() throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.archive));
         final String documentId = createArchiveId("/").toDocumentId();
         assertTrue(mArchive.isChildDocument(documentId,
@@ -267,7 +295,8 @@
                 createArchiveId("/dir1/cherries.txt").toDocumentId()));
     }
 
-    public void testQueryDocument() throws IOException {
+    @Test
+    public void testQueryDocument() throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.archive));
         final Cursor cursor = mArchive.queryDocument(
                 createArchiveId("/dir2/strawberries.txt").toDocumentId(),
@@ -285,12 +314,76 @@
                 cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
     }
 
-    public void testOpenDocument() throws IOException, ErrnoException {
+    private void queryDocumentByResIdWithMimeTypeAndVerify(@IdRes int resId, String mimeType)
+            throws IOException, CompressorException, ArchiveException {
+        loadArchive(mTestUtils.getSeekableDescriptor(resId),
+                mimeType);
+        final String documentId = createArchiveId("/hello/hello.txt").toDocumentId();
+
+        final Cursor cursor = mArchive.queryDocument(documentId, null);
+        cursor.moveToNext();
+
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)))
+                .isEqualTo(documentId);
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)))
+                .isEqualTo("hello.txt");
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)))
+                .isEqualTo("text/plain");
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)))
+                .isEqualTo(48);
+    }
+
+    @Test
+    public void archive_sevenZFile_containsList()
+            throws IOException, CompressorException, ArchiveException {
+        queryDocumentByResIdWithMimeTypeAndVerify(R.raw.hello_7z,
+                "application/x-7z-compressed");
+    }
+
+    @Test
+    public void archive_tar_containsList()
+            throws IOException, CompressorException, ArchiveException {
+        queryDocumentByResIdWithMimeTypeAndVerify(R.raw.hello_tar, "application/x-tar");
+    }
+
+    @Test
+    public void archive_tgz_containsList()
+            throws IOException, CompressorException, ArchiveException {
+        queryDocumentByResIdWithMimeTypeAndVerify(R.raw.hello_tgz,
+                "application/x-compressed-tar");
+    }
+
+    @Test
+    public void archive_tarXz_containsList()
+            throws IOException, CompressorException, ArchiveException {
+        queryDocumentByResIdWithMimeTypeAndVerify(R.raw.hello_tar_xz,
+                "application/x-xz-compressed-tar");
+    }
+
+    @Test
+    public void archive_tarBz_containsList()
+            throws IOException, CompressorException, ArchiveException {
+        queryDocumentByResIdWithMimeTypeAndVerify(R.raw.hello_tar_bz2,
+                "application/x-bzip-compressed-tar");
+    }
+
+    @Test
+    public void archive_tarBrotli_containsList()
+            throws IOException, CompressorException, ArchiveException {
+        queryDocumentByResIdWithMimeTypeAndVerify(R.raw.hello_tar_br,
+                "application/x-brotli-compressed-tar");
+    }
+
+    @Test
+    public void testOpenDocument()
+            throws IOException, CompressorException, ArchiveException, ErrnoException {
         loadArchive(mTestUtils.getSeekableDescriptor(R.raw.archive));
         commonTestOpenDocument();
     }
 
-    public void testOpenDocument_NonSeekable() throws IOException, ErrnoException {
+    @Test
+    public void testOpenDocument_NonSeekable()
+            throws IOException, CompressorException, ArchiveException, ErrnoException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.archive));
         commonTestOpenDocument();
     }
@@ -310,12 +403,14 @@
         }
     }
 
+    @Test
     public void testCanSeek() throws IOException {
         assertTrue(Archive.canSeek(mTestUtils.getSeekableDescriptor(R.raw.archive)));
         assertFalse(Archive.canSeek(mTestUtils.getNonSeekableDescriptor(R.raw.archive)));
     }
 
-    public void testBrokenArchive() throws IOException {
+    @Test
+    public void testBrokenArchive() throws IOException, CompressorException, ArchiveException {
         loadArchive(mTestUtils.getNonSeekableDescriptor(R.raw.archive));
         final Cursor cursor = mArchive.queryChildDocuments(
                 createArchiveId("/").toDocumentId(), null, null);
diff --git a/tests/unit/com/android/documentsui/archives/ResourcesProvider.java b/tests/unit/com/android/documentsui/archives/ResourcesProvider.java
index b9ddb92..64764ec 100644
--- a/tests/unit/com/android/documentsui/archives/ResourcesProvider.java
+++ b/tests/unit/com/android/documentsui/archives/ResourcesProvider.java
@@ -32,7 +32,7 @@
 import android.provider.DocumentsProvider;
 import android.webkit.MimeTypeMap;
 
-import libcore.io.IoUtils;
+import android.os.FileUtils;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -60,6 +60,11 @@
         RESOURCES.put("empty_dirs.zip", R.raw.empty_dirs);
         RESOURCES.put("images.zip", R.raw.images);
         RESOURCES.put("no_dirs.zip", R.raw.no_dirs);
+        RESOURCES.put("images.7z", R.raw.images_7z);
+        RESOURCES.put("images.tar", R.raw.images_tar);
+        RESOURCES.put("images.tar.xz", R.raw.images_tar_xz);
+        RESOURCES.put("images.tgz", R.raw.images_tgz);
+        RESOURCES.put("images.tar.br", R.raw.images_tar_br);
     }
 
     private ExecutorService mExecutor = null;
@@ -152,7 +157,7 @@
             row.add(Document.COLUMN_SIZE, fd.getLength());
         }
         finally {
-            IoUtils.closeQuietly(fd);
+            FileUtils.closeQuietly(fd);
         }
     }
 }
diff --git a/tests/unit/com/android/documentsui/archives/WriteableArchiveTest.java b/tests/unit/com/android/documentsui/archives/WriteableArchiveTest.java
index 93383c0..f066dc6 100644
--- a/tests/unit/com/android/documentsui/archives/WriteableArchiveTest.java
+++ b/tests/unit/com/android/documentsui/archives/WriteableArchiveTest.java
@@ -16,20 +16,18 @@
 
 package com.android.documentsui.archives;
 
-import com.android.documentsui.archives.WriteableArchive;
-import com.android.documentsui.tests.R;
-
 import android.database.Cursor;
-import android.content.Context;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
 import android.provider.DocumentsContract.Document;
-import android.support.test.InstrumentationRegistry;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import androidx.test.InstrumentationRegistry;
+
+import com.android.documentsui.archives.WriteableArchive;
+
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Enumeration;
diff --git a/tests/unit/com/android/documentsui/base/DocumentInfoTest.java b/tests/unit/com/android/documentsui/base/DocumentInfoTest.java
index 12b4165..6faa58a 100644
--- a/tests/unit/com/android/documentsui/base/DocumentInfoTest.java
+++ b/tests/unit/com/android/documentsui/base/DocumentInfoTest.java
@@ -16,41 +16,50 @@
 
 package com.android.documentsui.base;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.DocumentsContract;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.documentsui.base.DocumentInfo;
+import androidx.test.rule.provider.ProviderTestRule;
+
+import com.android.documentsui.InspectorProvider;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Set;
 
 @SmallTest
 public class DocumentInfoTest extends AndroidTestCase {
 
     private static final DocumentInfo TEST_DOC
             = createDocInfo("authority.a", "doc.1", "text/plain");
+    private static final String FOLDER_NAME = "Top";
+    private static final String FILE_NAME = InspectorProvider.OPEN_IN_PROVIDER_TEST;
 
-    public void testEquals() throws Exception {
-        assertEquals(TEST_DOC, TEST_DOC);
-        assertEquals(TEST_DOC, createDocInfo("authority.a", "doc.1", "text/plain"));
-    }
+    private Context mContext;
+    private ContentResolver mResolver;
 
-    public void testEquals_HandlesNulls() throws Exception {
-        assertFalse(TEST_DOC.equals(null));
-    }
+    @Rule
+    private ProviderTestRule mProviderTestRule = new ProviderTestRule.Builder(
+            InspectorProvider.class, InspectorProvider.AUTHORITY).build();
 
-    public void testEquals_HandlesNullFields() throws Exception {
-        assertFalse(TEST_DOC.equals(new DocumentInfo()));
-        assertFalse(new DocumentInfo().equals(TEST_DOC));
-    }
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
 
-    public void testNotEquals_differentAuthority() throws Exception {
-        assertFalse(TEST_DOC.equals(createDocInfo("authority.b", "doc.1", "text/plain")));
-    }
-
-    public void testNotEquals_differentDocId() throws Exception {
-        assertFalse(TEST_DOC.equals(createDocInfo("authority.a", "doc.2", "text/plain")));
-    }
-
-    public void testNotEquals_differentMimetype() throws Exception {
-        assertFalse(TEST_DOC.equals(createDocInfo("authority.a", "doc.1", "image/png")));
+        mContext = prepareContentResolverSource();
+        mResolver = mContext.getContentResolver();
     }
 
     private static DocumentInfo createDocInfo(String authority, String docId, String mimeType) {
@@ -61,4 +70,70 @@
         doc.deriveFields();
         return doc;
     }
+
+    protected Context prepareContentResolverSource() {
+        ContentResolver contentResolver = mProviderTestRule.getResolver();
+        Context context = mock(Context.class);
+        // inject ContentResolver
+        when(context.getContentResolver()).thenReturn(contentResolver);
+        return context;
+    }
+
+    @Test
+    public void testEquals() throws Exception {
+        assertEquals(TEST_DOC, TEST_DOC);
+        assertEquals(TEST_DOC, createDocInfo("authority.a", "doc.1", "text/plain"));
+    }
+
+    @Test
+    public void testEquals_HandlesNulls() throws Exception {
+        assertFalse(TEST_DOC.equals(null));
+    }
+
+    @Test
+    public void testEquals_HandlesNullFields() throws Exception {
+        assertFalse(TEST_DOC.equals(new DocumentInfo()));
+        assertFalse(new DocumentInfo().equals(TEST_DOC));
+    }
+
+    @Test
+    public void testNotEquals_differentAuthority() throws Exception {
+        assertFalse(TEST_DOC.equals(createDocInfo("authority.b", "doc.1", "text/plain")));
+    }
+
+    @Test
+    public void testNotEquals_differentDocId() throws Exception {
+        assertFalse(TEST_DOC.equals(createDocInfo("authority.a", "doc.2", "text/plain")));
+    }
+
+    @Test
+    public void testNotEquals_differentMimetype() throws Exception {
+        assertFalse(TEST_DOC.equals(createDocInfo("authority.a", "doc.1", "image/png")));
+    }
+
+    @Test
+    public void testFolderMimeTypeFromUri() throws Exception {
+        final Uri validUri = DocumentsContract.buildDocumentUri(
+                InspectorProvider.AUTHORITY, FOLDER_NAME);
+
+        final Set<String> mimeTypes = new HashSet<>();
+        DocumentInfo.addMimeTypes(mResolver, validUri, mimeTypes);
+
+        assertThat(mimeTypes.size()).isEqualTo(1);
+
+        assertThat(mimeTypes.contains(DocumentsContract.Document.MIME_TYPE_DIR)).isTrue();
+    }
+
+    @Test
+    public void testFileMimeTypeFromUri() throws Exception {
+        final Uri validUri = DocumentsContract.buildDocumentUri(
+                InspectorProvider.AUTHORITY, FILE_NAME);
+
+        final Set<String> mimeTypes = new HashSet<>();
+        DocumentInfo.addMimeTypes(mResolver, validUri, mimeTypes);
+
+        assertThat(mimeTypes.size()).isEqualTo(1);
+
+        assertThat(mimeTypes.contains("text/plain")).isTrue();
+    }
 }
diff --git a/tests/unit/com/android/documentsui/base/DocumentStackTest.java b/tests/unit/com/android/documentsui/base/DocumentStackTest.java
index bce96a6..b776111 100644
--- a/tests/unit/com/android/documentsui/base/DocumentStackTest.java
+++ b/tests/unit/com/android/documentsui/base/DocumentStackTest.java
@@ -18,12 +18,14 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
+import static junit.framework.TestCase.assertNotNull;
 import static junit.framework.TestCase.assertNull;
 import static junit.framework.TestCase.assertTrue;
 
 import android.provider.DocumentsContract;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.testing.Parcelables;
 
@@ -187,4 +189,14 @@
             return true;
         });
     }
+
+    @Test
+    public void testIsRecent() {
+        final RootInfo rootRecent = new RootInfo();
+        mStack.changeRoot(rootRecent);
+
+        assertEquals(1, mStack.size());
+        assertEquals(true, mStack.isRecents());
+        assertNotNull(mStack.peek().derivedUri);
+    }
 }
diff --git a/tests/unit/com/android/documentsui/base/StateTest.java b/tests/unit/com/android/documentsui/base/StateTest.java
index 1cbfc49..58dfb68 100644
--- a/tests/unit/com/android/documentsui/base/StateTest.java
+++ b/tests/unit/com/android/documentsui/base/StateTest.java
@@ -18,10 +18,13 @@
 
 
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Intent;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -57,4 +60,87 @@
 
         assertArrayEquals(new String[] { MIME_TYPES[0] }, mState.acceptMimes);
     }
+
+    @Test
+    public void testShouldShowPreview_actionBrowse() {
+        mState.action = State.ACTION_BROWSE;
+
+        assertFalse(mState.shouldShowPreview());
+    }
+
+    @Test
+    public void testShouldShowPreview_actionOpen() {
+        mState.action = State.ACTION_OPEN;
+
+        assertTrue(mState.shouldShowPreview());
+    }
+
+    @Test
+    public void testShouldShowPreview_actionGetContent() {
+        mState.action = State.ACTION_GET_CONTENT;
+
+        assertTrue(mState.shouldShowPreview());
+    }
+
+    @Test
+    public void testShouldShowPreview_actionOpenTree() {
+        mState.action = State.ACTION_OPEN_TREE;
+
+        assertTrue(mState.shouldShowPreview());
+    }
+
+    public void testPhotoPicking_onlyOneImageType() {
+        mIntent.putExtra(Intent.EXTRA_MIME_TYPES, MIME_TYPES[0]);
+        mState.initAcceptMimes(mIntent, "*/*");
+        mState.action = State.ACTION_GET_CONTENT;
+
+        assertTrue(mState.isPhotoPicking());
+    }
+
+    @Test
+    public void testPhotoPicking_allImageTypes() {
+        mIntent.putExtra(Intent.EXTRA_MIME_TYPES, MIME_TYPES);
+        mState.initAcceptMimes(mIntent, "*/*");
+        mState.action = State.ACTION_GET_CONTENT;
+
+        assertTrue(mState.isPhotoPicking());
+    }
+
+    @Test
+    public void testPhotoPicking_noImageType() {
+        final String[] mimeTypes = { "audio/mp3", "video/mp4" };
+        mIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
+        mState.initAcceptMimes(mIntent, "*/*");
+        mState.action = State.ACTION_GET_CONTENT;
+
+        assertFalse(mState.isPhotoPicking());
+    }
+
+    @Test
+    public void testPhotoPicking_oneIsNotImageType() {
+        final String[] mimeTypes = { "image/gif", "image/jpg", "audio/mp3" };
+        mIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
+        mState.initAcceptMimes(mIntent, "*/*");
+        mState.action = State.ACTION_GET_CONTENT;
+
+        assertFalse(mState.isPhotoPicking());
+    }
+
+    @Test
+    public void testPhotoPicking_browseMode() {
+        mState.initAcceptMimes(mIntent, "*/*");
+        mState.action = State.ACTION_BROWSE;
+
+        assertFalse(mState.isPhotoPicking());
+    }
+
+    @Test
+    public void testPhotoPicking_nullExrta() {
+        final String[] mimeTypes = null;
+        mIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
+        mState.initAcceptMimes(mIntent, "*/*");
+        mState.action = State.ACTION_GET_CONTENT;
+
+        assertFalse(mState.isPhotoPicking());
+    }
 }
diff --git a/tests/unit/com/android/documentsui/clipping/ClipStorageTest.java b/tests/unit/com/android/documentsui/clipping/ClipStorageTest.java
index 836c794..3af833a 100644
--- a/tests/unit/com/android/documentsui/clipping/ClipStorageTest.java
+++ b/tests/unit/com/android/documentsui/clipping/ClipStorageTest.java
@@ -17,16 +17,19 @@
 package com.android.documentsui.clipping;
 
 import static com.android.documentsui.clipping.ClipStorage.NUM_OF_SLOTS;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.annotation.MainThread;
 import android.content.SharedPreferences;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.testing.TestScheduledExecutorService;
 
@@ -44,6 +47,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@MainThread
 public class ClipStorageTest {
     private static final String PREF_NAME = "pref";
     private static final List<Uri> TEST_URIS = createList(
@@ -61,7 +65,8 @@
 
     @Before
     public void setUp() {
-        mPref = InstrumentationRegistry.getContext().getSharedPreferences(PREF_NAME, 0);
+        mPref = InstrumentationRegistry.getInstrumentation().getTargetContext()
+                .getSharedPreferences(PREF_NAME, 0);
         File clipDir = ClipStorage.prepareStorage(folder.getRoot());
         mStorage = new ClipStorage(clipDir, mPref);
 
diff --git a/tests/unit/com/android/documentsui/clipping/UrisSupplierTest.java b/tests/unit/com/android/documentsui/clipping/UrisSupplierTest.java
index 1cdb099..941d547 100644
--- a/tests/unit/com/android/documentsui/clipping/UrisSupplierTest.java
+++ b/tests/unit/com/android/documentsui/clipping/UrisSupplierTest.java
@@ -23,9 +23,10 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.provider.DocumentsContract;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.testing.TestScheduledExecutorService;
@@ -62,7 +63,8 @@
         mExecutor = new TestScheduledExecutorService();
         AsyncTask.setDefaultExecutor(mExecutor);
 
-        mPref = InstrumentationRegistry.getContext().getSharedPreferences(PREF_NAME, 0);
+        mPref = InstrumentationRegistry.getInstrumentation().getTargetContext()
+                .getSharedPreferences(PREF_NAME, 0);
         mStorage = new ClipStorage(folder.getRoot(), mPref);
     }
 
diff --git a/tests/unit/com/android/documentsui/dirlist/AccessibilityTest.java b/tests/unit/com/android/documentsui/dirlist/AccessibilityTest.java
index f3e607e..93b9ed6 100644
--- a/tests/unit/com/android/documentsui/dirlist/AccessibilityTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/AccessibilityTest.java
@@ -16,15 +16,19 @@
 
 package com.android.documentsui.dirlist;
 
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.database.Cursor;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.Space;
+
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.documentsui.testing.TestRecyclerView;
 import com.android.documentsui.testing.Views;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @SmallTest
@@ -34,13 +38,17 @@
 
     private TestRecyclerView mView;
     private AccessibilityEventRouter mAccessibilityDelegate;
-    private boolean mCallbackCalled = false;
+    private boolean mClickCallbackCalled = false;
+    private boolean mLongClickCallbackCalled = false;
 
     @Override
     public void setUp() throws Exception {
         mView = TestRecyclerView.create(ITEMS);
         mAccessibilityDelegate = new AccessibilityEventRouter(mView, (View v) -> {
-            mCallbackCalled = true;
+            mClickCallbackCalled = true;
+            return true;
+        }, (View v) -> {
+            mLongClickCallbackCalled = true;
             return true;
         });
         mView.setAccessibilityDelegateCompat(mAccessibilityDelegate);
@@ -53,11 +61,39 @@
         assertTrue(info.isSelected());
     }
 
+    public void testNullItemDetails_NoActionClick() throws Exception {
+        View item = Views.createTestView(true);
+        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+
+        List<RecyclerView.ViewHolder> holders = new ArrayList<>();
+        holders.add(new MessageHolder(mView.getContext(), new Space(mView.getContext())) {
+            @Override
+            public void bind(Cursor cursor, String modelId) {
+
+            }
+        });
+
+        mView.setHolders(holders);
+
+        mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info);
+        assertFalse(info.isClickable());
+    }
+
     public void test_routesAccessibilityClicks() throws Exception {
         View item = Views.createTestView(true);
         AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
         mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info);
-        mAccessibilityDelegate.getItemDelegate().performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_CLICK, null);
-        assertTrue(mCallbackCalled);
+        mAccessibilityDelegate.getItemDelegate()
+            .performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_CLICK, null);
+        assertTrue(mClickCallbackCalled);
+    }
+
+    public void test_routesAccessibilityLongClicks() throws Exception {
+        View item = Views.createTestView(true);
+        AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+        mAccessibilityDelegate.getItemDelegate().onInitializeAccessibilityNodeInfo(item, info);
+        mAccessibilityDelegate.getItemDelegate()
+            .performAccessibilityAction(item, AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, null);
+        assertTrue(mLongClickCallbackCalled);
     }
 }
diff --git a/tests/unit/com/android/documentsui/dirlist/AppsRowManagerTest.java b/tests/unit/com/android/documentsui/dirlist/AppsRowManagerTest.java
new file mode 100644
index 0000000..9577550
--- /dev/null
+++ b/tests/unit/com/android/documentsui/dirlist/AppsRowManagerTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2018 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.documentsui.dirlist;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.R;
+import com.android.documentsui.base.State;
+import com.android.documentsui.sidebar.AppItem;
+import com.android.documentsui.sidebar.Item;
+import com.android.documentsui.sidebar.RootItem;
+import com.android.documentsui.testing.TestActionHandler;
+import com.android.documentsui.testing.TestProvidersAccess;
+import com.android.documentsui.testing.TestResolveInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AppsRowManagerTest {
+
+    private AppsRowManager mAppsRowManager;
+
+    private ActionHandler mActionHandler;
+    private BaseActivity mActivity;
+    private State mState;
+
+    private View mAppsRow;
+    private LinearLayout mAppsGroup;
+
+    @Before
+    public void setUp() {
+        mActionHandler = new TestActionHandler();
+
+        mAppsRowManager = new AppsRowManager(mActionHandler);
+
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        LayoutInflater layoutInflater = LayoutInflater.from(context);
+        mState = new State();
+        mActivity = mock(BaseActivity.class);
+        mAppsRow = layoutInflater.inflate(R.layout.apps_row, null);
+        mAppsGroup = mAppsRow.findViewById(R.id.apps_row);
+
+        when(mActivity.getLayoutInflater()).thenReturn(layoutInflater);
+        when(mActivity.getDisplayState()).thenReturn(mState);
+        when(mActivity.findViewById(R.id.apps_row)).thenReturn(mAppsRow);
+        when(mActivity.findViewById(R.id.apps_group)).thenReturn(mAppsGroup);
+    }
+
+    @Test
+    public void testUpdateList_byRootItem() {
+        final List<Item> rootList = new ArrayList<>();
+        rootList.add(new RootItem(TestProvidersAccess.INSPECTOR, mActionHandler));
+        rootList.add(new RootItem(TestProvidersAccess.PICKLES, mActionHandler));
+
+        final List<AppsRowItemData> chipDataList = mAppsRowManager.updateList(rootList);
+
+        assertEquals(chipDataList.size(), rootList.size());
+        assertEquals(TestProvidersAccess.INSPECTOR.title, chipDataList.get(0).getTitle());
+        assertFalse(chipDataList.get(0).showExitIcon());
+        assertEquals(TestProvidersAccess.PICKLES.title, chipDataList.get(1).getTitle());
+        assertFalse(chipDataList.get(1).showExitIcon());
+    }
+
+    @Test
+    public void testUpdateList_byHybridItem() {
+        final String testPackageName = "com.test1";
+        final ResolveInfo info = TestResolveInfo.create();
+        info.activityInfo.packageName = testPackageName;
+
+        List<Item> hybridList = new ArrayList<>();
+        hybridList.add(new RootItem(TestProvidersAccess.INSPECTOR, mActionHandler));
+        hybridList.add(new AppItem(info, TestProvidersAccess.PICKLES.title, mActionHandler));
+
+        final List<AppsRowItemData> chipDataList = mAppsRowManager.updateList(hybridList);
+
+        assertEquals(chipDataList.size(), hybridList.size());
+        assertEquals(TestProvidersAccess.INSPECTOR.title, chipDataList.get(0).getTitle());
+        assertTrue(chipDataList.get(0) instanceof AppsRowItemData.RootData);
+        assertFalse(chipDataList.get(0).showExitIcon());
+        assertEquals(TestProvidersAccess.PICKLES.title, chipDataList.get(1).getTitle());
+        assertTrue(chipDataList.get(1) instanceof AppsRowItemData.AppData);
+        assertTrue(chipDataList.get(1).showExitIcon());
+    }
+
+    @Test
+    public void testUpdateView_matchedState_showRow() {
+        mState.action = State.ACTION_BROWSE;
+        mState.stack.changeRoot(TestProvidersAccess.RECENTS);
+        final List<Item> rootList = new ArrayList<>();
+        rootList.add(new RootItem(TestProvidersAccess.INSPECTOR, mActionHandler));
+        mAppsRowManager.updateList(rootList);
+
+        mAppsRowManager.updateView(mActivity);
+
+        assertEquals(View.VISIBLE, mAppsRow.getVisibility());
+        assertEquals(1, mAppsGroup.getChildCount());
+    }
+
+    @Test
+    public void testUpdateView_notInRecent_hideRow() {
+        mState.action = State.ACTION_BROWSE;
+        final List<Item> rootList = new ArrayList<>();
+        rootList.add(new RootItem(TestProvidersAccess.INSPECTOR, mActionHandler));
+        mAppsRowManager.updateList(rootList);
+
+        mState.stack.changeRoot(TestProvidersAccess.DOWNLOADS);
+
+        mAppsRowManager.updateView(mActivity);
+
+        assertEquals(View.GONE, mAppsRow.getVisibility());
+    }
+
+    @Test
+    public void testUpdateView_notHandledAction_hideRow() {
+        mState.action = State.ACTION_OPEN_TREE;
+
+        mState.stack.changeRoot(TestProvidersAccess.RECENTS);
+        final List<Item> rootList = new ArrayList<>();
+        rootList.add(new RootItem(TestProvidersAccess.INSPECTOR, mActionHandler));
+        mAppsRowManager.updateList(rootList);
+
+        mAppsRowManager.updateView(mActivity);
+
+        assertEquals(View.GONE, mAppsRow.getVisibility());
+    }
+
+    @Test
+    public void testUpdateView_noItems_hideRow() {
+        mState.action = State.ACTION_BROWSE;
+        mState.stack.changeRoot(TestProvidersAccess.RECENTS);
+
+        final List<Item> rootList = new ArrayList<>();
+        mAppsRowManager.updateList(rootList);
+
+        mAppsRowManager.updateView(mActivity);
+
+        assertEquals(View.GONE, mAppsRow.getVisibility());
+    }
+}
+
diff --git a/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java b/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java
index c25e43f..7a7b00e 100644
--- a/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java
@@ -20,13 +20,15 @@
 import android.database.Cursor;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
-import android.support.test.filters.MediumTest;
-import android.support.v7.widget.RecyclerView;
 import android.test.AndroidTestCase;
 import android.view.ViewGroup;
 
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.filters.MediumTest;
+
 import com.android.documentsui.ActionHandler;
 import com.android.documentsui.Model;
+import com.android.documentsui.ModelId;
 import com.android.documentsui.base.Features;
 import com.android.documentsui.base.State;
 import com.android.documentsui.testing.TestActionHandler;
@@ -71,10 +73,10 @@
         mEnv.model.createFile("b");  // id will be "2"
         mEnv.model.update();
 
-        assertEquals(0, mAdapter.getPosition("1"));
+        assertEquals(0, mAdapter.getPosition(ModelId.build(AUTHORITY, "1")));
         // adapter inserts a view between item 0 and 1 to force layout
         // break between folders and files. This is reflected by an offset position.
-        assertEquals(2, mAdapter.getPosition("2"));
+        assertEquals(2, mAdapter.getPosition(ModelId.build(AUTHORITY, "2")));
     }
 
     // Tests that the item count is correct for a directory containing only subdirs.
diff --git a/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java b/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java
index f2187e4..2574f73 100644
--- a/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DocumentHolderTest.java
@@ -20,8 +20,6 @@
 import android.database.Cursor;
 import android.graphics.Rect;
 import android.os.SystemClock;
-import android.support.test.filters.SmallTest;
-import android.support.test.filters.Suppress;
 import android.test.AndroidTestCase;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -29,8 +27,10 @@
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.filters.Suppress;
+
 import com.android.documentsui.R;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
 
 @SmallTest
 public class DocumentHolderTest extends AndroidTestCase {
@@ -99,9 +99,9 @@
                 );
     }
 
-    private class TestListener extends KeyboardEventListener {
+    private class TestListener extends KeyboardEventListener<DocumentItemDetails> {
         @Override
-        public boolean onKey(ItemDetails item, int keyCode, KeyEvent event) {
+        public boolean onKey(DocumentItemDetails item, int keyCode, KeyEvent event) {
             return false;
         }
 
diff --git a/tests/unit/com/android/documentsui/dirlist/DragHostTest.java b/tests/unit/com/android/documentsui/dirlist/DragHostTest.java
index 7db69dc..4fc53c1 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragHostTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragHostTest.java
@@ -20,18 +20,18 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.content.ClipData;
-import android.database.Cursor;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.DragEvent;
 import android.view.View;
 
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.SelectionHelpers;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.files.TestActivity;
-import com.android.documentsui.selection.SelectionHelper;
 import com.android.documentsui.testing.ClipDatas;
 import com.android.documentsui.testing.DragEvents;
-import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestActionHandler;
 import com.android.documentsui.testing.TestDragAndDropManager;
 import com.android.documentsui.testing.TestEnv;
@@ -55,7 +55,7 @@
     private TestDialogController mDialogs;
     private DragHost<?> dragHost;
     private TestDragAndDropManager mDragAndDropManager;
-    private SelectionHelper mSelectionMgr;
+    private SelectionTracker<String> mSelectionMgr;
     private boolean mIsDocumentView;
     private DocumentHolder mNextDocumentHolder;
     private DocumentInfo mNextDocumentInfo;
diff --git a/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java b/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
index faa86a3..5bac033 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
@@ -18,30 +18,28 @@
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
 
 import android.provider.DocumentsContract;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.MotionEvent;
 import android.view.View;
 
+import androidx.recyclerview.selection.MutableSelection;
+import androidx.recyclerview.selection.Selection;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.DocsSelectionHelper;
 import com.android.documentsui.MenuManager.SelectionDetails;
+import com.android.documentsui.SelectionHelpers;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Events;
 import com.android.documentsui.base.Providers;
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.DragStartListener.RuntimeDragStartListener;
-import com.android.documentsui.selection.MutableSelection;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.TestItemDetailsLookup;
-import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestDragAndDropManager;
 import com.android.documentsui.testing.TestEvents;
 import com.android.documentsui.testing.TestSelectionDetails;
 import com.android.documentsui.testing.Views;
-import com.android.internal.widget.RecyclerView;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -79,7 +77,6 @@
         mListener = new DragStartListener.RuntimeDragStartListener(
                 null, // icon helper
                 state,
-                mDocLookup,
                 mSelectionMgr,
                 mSelectionDetails,
                 // view finder
@@ -91,7 +88,7 @@
                     return mViewModelId;
                 },
                 // docInfo Converter
-                (Selection selection) -> {
+                (Selection<String> selection) -> {
                     return new ArrayList<>();
                 },
                 mManager);
@@ -107,47 +104,29 @@
 
     @Test
     public void testMouseEvent() {
-        assertTrue(Events.isMouseDragEvent(mEvent.build()));
+        MotionEvent e = mEvent.build();
+        // Assert it is a mouse drag event.
+        assertTrue(Events.isMouseEvent(e));
+        assertTrue(e.getActionMasked() == MotionEvent.ACTION_MOVE);
+        assertTrue(e.isButtonPressed(MotionEvent.BUTTON_PRIMARY));
     }
 
     @Test
     public void testDragStarted_OnMouseMove() {
-        assertTrue(mListener.onMouseDragEvent(mEvent.build()));
+        assertTrue(mListener.onDragEvent(mEvent.build()));
         mManager.startDragHandler.assertCalled();
     }
 
     @Test
     public void testDragNotStarted_NonModelBackedView() {
         mViewModelId = null;
-        assertFalse(mListener.onMouseDragEvent(mEvent.build()));
+        assertFalse(mListener.onDragEvent(mEvent.build()));
         mManager.startDragHandler.assertNotCalled();
     }
 
     @Test
-    public void testThrows_OnNonMouseMove() {
-        assertThrows(mEvent.touch().build());
-    }
-
-    @Test
-    public void testThrows_OnNonPrimaryMove() {
-        mEvent.releaseButton(MotionEvent.BUTTON_PRIMARY);
-        assertThrows(mEvent.pressButton(MotionEvent.BUTTON_SECONDARY).build());
-    }
-
-    @Test
-    public void testThrows_OnNonMove() {
-        assertThrows(mEvent.action(MotionEvent.ACTION_UP).build());
-    }
-
-    @Test
-    public void testThrows_WhenNotOnItem() {
-        mDocLookup.initAt(RecyclerView.NO_POSITION);
-        assertThrows(mEvent.build());
-    }
-
-    @Test
     public void testDragStart_nonSelectedItem() {
-        Selection selection = mListener.getSelectionToBeCopied("1234",
+        Selection<String> selection = mListener.getSelectionToBeCopied("1234",
                 mEvent.action(MotionEvent.ACTION_MOVE).build());
         assertTrue(selection.size() == 1);
         assertTrue(selection.contains("1234"));
@@ -155,7 +134,7 @@
 
     @Test
     public void testDragStart_selectedItem() {
-        MutableSelection selection = new MutableSelection();
+        MutableSelection<String> selection = new MutableSelection<>();
         selection.add("1234");
         selection.add("5678");
         mSelectionMgr.replaceSelection(selection);
@@ -169,7 +148,7 @@
 
     @Test
     public void testDragStart_newNonSelectedItem() {
-        MutableSelection selection = new MutableSelection();
+        MutableSelection<String> selection = new MutableSelection<>();
         selection.add("5678");
         mSelectionMgr.replaceSelection(selection);
 
@@ -183,7 +162,7 @@
 
     @Test
     public void testCtrlDragStart_newNonSelectedItem() {
-        MutableSelection selection = new MutableSelection();
+        MutableSelection<String> selection = new MutableSelection<>();
         selection.add("5678");
         mSelectionMgr.replaceSelection(selection);
 
@@ -193,11 +172,4 @@
         assertTrue(selection.contains("1234"));
         assertTrue(selection.contains("5678"));
     }
-
-    private void assertThrows(MotionEvent e) {
-        try {
-            mListener.onMouseDragEvent(e);
-            fail();
-        } catch (IllegalArgumentException expected) {}
-    }
 }
diff --git a/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java b/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java
index fdf9a59..bce45e0 100644
--- a/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/KeyInputHandlerTest.java
@@ -18,17 +18,15 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.support.annotation.Nullable;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.KeyEvent;
 
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.documentsui.selection.testing.SelectionPredicates;
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestData;
-import com.android.documentsui.testing.SelectionHelpers;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.Selection;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.SelectionHelpers;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,21 +41,19 @@
     private static final List<String> ITEMS = TestData.create(100);
 
     private KeyInputHandler mInputHandler;
-    private SelectionHelper mSelectionHelper;
+    private SelectionTracker<String> mSelectionHelper;
     private TestFocusHandler mFocusHandler;
-    private SelectionProbe mSelection;
     private TestCallbacks mCallbacks;
 
     @Before
     public void setUp() {
         mSelectionHelper = SelectionHelpers.createTestInstance(ITEMS);
-        mSelection = new SelectionProbe(mSelectionHelper);
         mFocusHandler = new TestFocusHandler();
         mCallbacks = new TestCallbacks();
 
         mInputHandler = new KeyInputHandler(
                 mSelectionHelper,
-                SelectionPredicates.CAN_SET_ANYTHING,
+                SelectionHelpers.CAN_SET_ANYTHING,
                 mCallbacks);
     }
 
@@ -69,30 +65,33 @@
         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP);
         mInputHandler.onKey(null, event.getKeyCode(), event);
 
-        mSelection.assertNoSelection();
+        Selection<String> selection = mSelectionHelper.getSelection();
+        assertEquals(selection.toString(), 0, selection.size());
     }
 
-    private static final class TestCallbacks extends KeyInputHandler.Callbacks {
+    private static final class TestCallbacks
+            extends KeyInputHandler.Callbacks<DocumentItemDetails> {
 
-        private @Nullable ItemDetails mActivated;
+        private @Nullable DocumentItemDetails mActivated;
 
         @Override
-        public boolean isInteractiveItem(ItemDetails item, KeyEvent e) {
+        public boolean isInteractiveItem(DocumentItemDetails item, KeyEvent e) {
             return true;
         }
 
         @Override
-        public boolean onItemActivated(ItemDetails item, KeyEvent e) {
+        public boolean onItemActivated(DocumentItemDetails item, KeyEvent e) {
             mActivated = item;
             return false;
         }
 
-        private void assertActivated(ItemDetails expected) {
+        private void assertActivated(DocumentItemDetails expected) {
             assertEquals(expected, mActivated);
         }
 
         @Override
-        public void onPerformHapticFeedback() {
+        public boolean onFocusItem(DocumentItemDetails details, int keyCode, KeyEvent event) {
+            return true;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java b/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
index 88ea13d..9fd6b2d 100644
--- a/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
@@ -16,12 +16,12 @@
 
 package com.android.documentsui.dirlist;
 
-import android.app.PendingIntent;
 import android.content.Context;
 import android.database.Cursor;
-import android.support.test.filters.MediumTest;
 import android.test.AndroidTestCase;
 
+import androidx.test.filters.MediumTest;
+
 import com.android.documentsui.ActionHandler;
 import com.android.documentsui.Model;
 import com.android.documentsui.base.Features;
diff --git a/tests/unit/com/android/documentsui/selection/TestItemDetails.java b/tests/unit/com/android/documentsui/dirlist/TestItemDetails.java
similarity index 90%
rename from tests/unit/com/android/documentsui/selection/TestItemDetails.java
rename to tests/unit/com/android/documentsui/dirlist/TestItemDetails.java
index b943247..75e8e24 100644
--- a/tests/unit/com/android/documentsui/selection/TestItemDetails.java
+++ b/tests/unit/com/android/documentsui/dirlist/TestItemDetails.java
@@ -13,14 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.documentsui.selection;
+package com.android.documentsui.dirlist;
 
 import android.view.MotionEvent;
 
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
+import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
+
 import com.android.internal.widget.RecyclerView;
 
-public final class TestItemDetails extends ItemDetails {
+/**
+ * Test implementation of ItemDetails.
+ */
+public final class TestItemDetails extends ItemDetails<String> {
 
     // DocumentsAdapter.ITEM_TYPE_DOCUMENT
     private int mViewType = -1;
@@ -60,7 +64,6 @@
         mInSelectionHotspot = over;
     }
 
-    @Override
     public int getItemViewType() {
         return mViewType;
     }
@@ -97,7 +100,7 @@
     }
 
     @Override
-    public String getStableId() {
+    public String getSelectionKey() {
         return mStableId;
     }
 
diff --git a/tests/unit/com/android/documentsui/dirlist/TestItemDetailsLookup.java b/tests/unit/com/android/documentsui/dirlist/TestItemDetailsLookup.java
new file mode 100644
index 0000000..3ae3e26
--- /dev/null
+++ b/tests/unit/com/android/documentsui/dirlist/TestItemDetailsLookup.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 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.documentsui.dirlist;
+
+import android.view.MotionEvent;
+
+import com.android.documentsui.DocsSelectionHelper.DocDetailsLookup;
+
+import javax.annotation.Nullable;
+
+/**
+ * Test implementation of ItemDetailsLookup.
+ */
+public class TestItemDetailsLookup extends DocDetailsLookup {
+
+    private @Nullable TestItemDetails mDoc;
+
+    @Override
+    public @Nullable ItemDetails<String> getItemDetails(MotionEvent e) {
+        return mDoc;
+    }
+
+    /**
+     * Creates/installs/returns a new test document. Subsequent calls to
+     * any EventDocLookup methods will consult the newly created doc.
+     */
+    public TestItemDetails initAt(int position) {
+        TestItemDetails doc = new TestItemDetails();
+        doc.at(position);
+        mDoc = doc;
+        return doc;
+    }
+
+    public void reset() {
+        mDoc = null;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
index 34c3142..de4f7fa 100644
--- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
@@ -23,6 +23,7 @@
 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraList;
 import static com.android.documentsui.testing.IntentAsserts.assertHasExtraUri;
 import static com.android.documentsui.testing.IntentAsserts.assertTargetsComponent;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -31,6 +32,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.DownloadManager;
 import android.app.PendingIntent;
 import android.content.ClipData;
 import android.content.Intent;
@@ -38,13 +40,16 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Path;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.Pair;
 import android.view.DragEvent;
 
+import androidx.core.util.Preconditions;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.AbstractActionHandler;
+import com.android.documentsui.ModelId;
 import com.android.documentsui.R;
 import com.android.documentsui.TestActionModeAddons;
 import com.android.documentsui.archives.ArchivesProvider;
@@ -63,7 +68,6 @@
 import com.android.documentsui.testing.TestFeatures;
 import com.android.documentsui.testing.TestProvidersAccess;
 import com.android.documentsui.ui.TestDialogController;
-import com.android.internal.util.Preconditions;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -356,18 +360,20 @@
         mActivity.currentRoot = TestProvidersAccess.HOME;
         mEnv.docs.nextDocument = TestEnv.FILE_ARCHIVE;
 
-        mHandler.openDocument(TestEnv.FILE_ARCHIVE, ActionHandler.VIEW_TYPE_PREVIEW,
-                ActionHandler.VIEW_TYPE_REGULAR);
+        final boolean result = mHandler.openDocument(TestEnv.FILE_ARCHIVE,
+                ActionHandler.VIEW_TYPE_PREVIEW, ActionHandler.VIEW_TYPE_REGULAR);
         assertEquals(TestEnv.FILE_ARCHIVE, mEnv.state.stack.peek());
+        assertEquals(false, result);
     }
 
     @Test
     public void testDocumentPicked_OpensDirectories() throws Exception {
         mActivity.currentRoot = TestProvidersAccess.HOME;
 
-        mHandler.openDocument(TestEnv.FOLDER_1, ActionHandler.VIEW_TYPE_PREVIEW,
-                ActionHandler.VIEW_TYPE_REGULAR);
+        final boolean result = mHandler.openDocument(TestEnv.FOLDER_1,
+                ActionHandler.VIEW_TYPE_PREVIEW, ActionHandler.VIEW_TYPE_REGULAR);
         assertEquals(TestEnv.FOLDER_1, mEnv.state.stack.peek());
+        assertEquals(false, result);
     }
 
     @Test
@@ -379,6 +385,17 @@
     }
 
     @Test
+    public void testInitLocation_LaunchToStackLocation() {
+        DocumentStack path = new DocumentStack(Roots.create("123"), mEnv.model.getDocument("1"));
+
+        Intent intent = LauncherActivity.createLaunchIntent(mActivity);
+        intent.putExtra(Shared.EXTRA_STACK, (Parcelable) path);
+
+        mHandler.initLocation(intent);
+        mActivity.refreshCurrentRootAndDirectory.assertCalled();
+    }
+
+    @Test
     public void testInitLocation_RestoresIfStackIsLoaded() throws Exception {
         mEnv.state.stack.changeRoot(TestProvidersAccess.DOWNLOADS);
         mEnv.state.stack.push(TestEnv.FOLDER_0);
@@ -396,8 +413,20 @@
     }
 
     @Test
-    public void testInitLocation_DefaultsToDownloads() throws Exception {
+    public void testInitLocation_DefaultsToRecent() throws Exception {
         mActivity.resources.bools.put(R.bool.show_documents_root, false);
+        mFeatures.forceDefaultRoot = false;
+
+        mHandler.initLocation(mActivity.getIntent());
+        assertRecentPicked();
+    }
+
+    @Test
+    public void testInitLocation_forceDefaultsToRoot() throws Exception {
+        mActivity.resources.bools.put(R.bool.show_documents_root, false);
+        mFeatures.forceDefaultRoot = true;
+        mActivity.resources.strings.put(R.string.default_root_uri,
+                TestProvidersAccess.DOWNLOADS.getUri().toString());
 
         mHandler.initLocation(mActivity.getIntent());
         assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
@@ -406,13 +435,38 @@
     @Test
     public void testInitLocation_DocumentsRootEnabled() throws Exception {
         mActivity.resources.bools.put(R.bool.show_documents_root, true);
-        mActivity.resources.strings.put(R.string.default_root_uri, TestProvidersAccess.HOME.getUri().toString());
+        mFeatures.forceDefaultRoot = true;
+        mActivity.resources.strings.put(R.string.default_root_uri,
+                TestProvidersAccess.HOME.getUri().toString());
 
         mHandler.initLocation(mActivity.getIntent());
         assertRootPicked(TestProvidersAccess.HOME.getUri());
     }
 
     @Test
+    public void testInitLocation_BrowseRootWithoutRootId() throws Exception {
+        Intent intent = mActivity.getIntent();
+        intent.setAction(Intent.ACTION_VIEW);
+        intent.setData(DocumentsContract.buildRootsUri(TestProvidersAccess.HAMMY.authority));
+
+        mHandler.initLocation(intent);
+        assertRootPicked(TestProvidersAccess.HAMMY.getUri());
+    }
+
+    @Test
+    public void testInitLocation_BrowseRootWrongAuthority_ShowDefault() throws Exception {
+        Intent intent = mActivity.getIntent();
+        intent.setAction(Intent.ACTION_VIEW);
+        intent.setData(DocumentsContract.buildRootsUri("com.test.wrongauthority"));
+        mActivity.resources.strings.put(R.string.default_root_uri,
+                TestProvidersAccess.HOME.getUri().toString());
+        mFeatures.forceDefaultRoot = false;
+
+        mHandler.initLocation(intent);
+        assertRecentPicked();
+    }
+
+    @Test
     public void testInitLocation_BrowseRoot() throws Exception {
         Intent intent = mActivity.getIntent();
         intent.setAction(Intent.ACTION_VIEW);
@@ -451,6 +505,15 @@
     }
 
     @Test
+    public void testInitLocation_LaunchToDownloads() throws Exception {
+        Intent intent = mActivity.getIntent();
+        intent.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
+
+        mHandler.initLocation(intent);
+        assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
+    }
+
+    @Test
     public void testDragAndDrop_OnReadOnlyRoot() throws Exception {
         RootInfo root = new RootInfo(); // root by default has no SUPPORT_CREATE flag
         DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, null, null, null,
@@ -510,7 +573,8 @@
     public void testRefresh() throws Exception {
         refreshAnswer = false;
         mEnv.populateStack();
-        mHandler.refreshDocument(mEnv.model.getDocument("1"), (boolean answer) -> {
+        mHandler.refreshDocument(mEnv.model.getDocument(
+                ModelId.build(TestProvidersAccess.HOME.authority, "1")), (boolean answer) -> {
             refreshAnswer = answer;
         });
 
@@ -632,6 +696,12 @@
         assertEquals(expectedUri, root.getUri());
     }
 
+    private void assertRecentPicked() throws Exception{
+        mEnv.beforeAsserts();
+        assertEquals(TestProvidersAccess.RECENTS, mEnv.state.stack.getRoot());
+        mActivity.refreshCurrentRootAndDirectory.assertCalled();
+    }
+
     private ActionHandler<TestActivity> createHandler() {
         return new ActionHandler<>(
                 mActivity,
diff --git a/tests/unit/com/android/documentsui/files/ActivityInputHandlerTest.java b/tests/unit/com/android/documentsui/files/ActivityInputHandlerTest.java
index b579dbe..b184e36 100644
--- a/tests/unit/com/android/documentsui/files/ActivityInputHandlerTest.java
+++ b/tests/unit/com/android/documentsui/files/ActivityInputHandlerTest.java
@@ -18,11 +18,12 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/unit/com/android/documentsui/files/MenuManagerTest.java b/tests/unit/com/android/documentsui/files/MenuManagerTest.java
index c30d572..6f79c94 100644
--- a/tests/unit/com/android/documentsui/files/MenuManagerTest.java
+++ b/tests/unit/com/android/documentsui/files/MenuManagerTest.java
@@ -17,23 +17,23 @@
 package com.android.documentsui.files;
 
 import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertTrue;
 
 import android.net.Uri;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.AndroidTestCase;
+
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.R;
+import com.android.documentsui.SelectionHelpers;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
-import com.android.documentsui.dirlist.TestContext;
 import com.android.documentsui.dirlist.TestData;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.testing.SelectionHelpers;
 import com.android.documentsui.testing.TestDirectoryDetails;
 import com.android.documentsui.testing.TestEnv;
 import com.android.documentsui.testing.TestFeatures;
@@ -89,18 +89,22 @@
     private TestMenuItem actionModeRename;
     private TestMenuItem actionModeViewInOwner;
     private TestMenuItem actionModeInspector;
+    private TestMenuItem actionModeSort;
 
     /* Option Menu items */
     private TestMenuItem optionSearch;
     private TestMenuItem optionDebug;
-    private TestMenuItem optionGrid;
-    private TestMenuItem optionList;
     private TestMenuItem optionNewWindow;
     private TestMenuItem optionCreateDir;
     private TestMenuItem optionSelectAll;
     private TestMenuItem optionAdvanced;
     private TestMenuItem optionSettings;
     private TestMenuItem optionInspector;
+    private TestMenuItem optionSort;
+
+    /* Sub Option Menu items */
+    private TestMenuItem subOptionGrid;
+    private TestMenuItem subOptionList;
 
     private TestFeatures features;
     private TestSelectionDetails selectionDetails;
@@ -112,7 +116,7 @@
     private State state = new State();
     private MenuManager mgr;
     private TestActivity activity = TestActivity.create(TestEnv.create());
-    private SelectionHelper selectionManager;
+    private SelectionTracker<String> selectionManager;
 
     @Before
     public void setUp() {
@@ -140,7 +144,6 @@
         rootSettings = testMenu.findItem(R.id.root_menu_settings);
 
         // Menu actions (including overflow) when action mode *is* active.
-        actionModeOpen = testMenu.findItem(R.id.action_menu_open);
         actionModeOpenWith = testMenu.findItem(R.id.action_menu_open_with);
         actionModeShare = testMenu.findItem(R.id.action_menu_share);
         actionModeDelete = testMenu.findItem(R.id.action_menu_delete);
@@ -152,25 +155,29 @@
         actionModeRename = testMenu.findItem(R.id.action_menu_rename);
         actionModeInspector = testMenu.findItem(R.id.action_menu_inspect);
         actionModeViewInOwner = testMenu.findItem(R.id.action_menu_view_in_owner);
+        actionModeSort = testMenu.findItem(R.id.action_menu_sort);
 
         // Menu actions (including overflow) when action mode is not active.
         optionSearch = testMenu.findItem(R.id.option_menu_search);
         optionDebug = testMenu.findItem(R.id.option_menu_debug);
-        optionGrid = testMenu.findItem(R.id.option_menu_grid);
-        optionList = testMenu.findItem(R.id.option_menu_list);
         optionNewWindow = testMenu.findItem(R.id.option_menu_new_window);
         optionCreateDir = testMenu.findItem(R.id.option_menu_create_dir);
         optionSelectAll = testMenu.findItem(R.id.option_menu_select_all);
         optionAdvanced = testMenu.findItem(R.id.option_menu_advanced);
         optionSettings = testMenu.findItem(R.id.option_menu_settings);
         optionInspector = testMenu.findItem(R.id.option_menu_inspect);
+        optionSort = testMenu.findItem(R.id.option_menu_sort);
+
+        // Menu actions on root title row.
+        subOptionGrid = testMenu.findItem(R.id.sub_menu_grid);
+        subOptionList = testMenu.findItem(R.id.sub_menu_list);
 
         features = new TestFeatures();
 
         // These items by default are visible
         testMenu.findItem(R.id.dir_menu_select_all).setVisible(true);
         testMenu.findItem(R.id.option_menu_select_all).setVisible(true);
-        testMenu.findItem(R.id.option_menu_list).setVisible(true);
+        testMenu.findItem(R.id.sub_menu_list).setVisible(true);
 
         selectionDetails = new TestSelectionDetails();
         dirDetails = new TestDirectoryDetails();
@@ -217,6 +224,8 @@
         actionModeExtractTo.assertInvisible();
         actionModeMoveTo.assertEnabled();
         actionModeViewInOwner.assertInvisible();
+        actionModeSort.assertVisible();
+        actionModeSort.assertEnabled();
     }
 
     @Test
@@ -288,6 +297,26 @@
     }
 
     @Test
+    public void testActionsMenu_cantViewInOwner_noSelection() {
+        // Simulate empty selection
+        selectionManager = SelectionHelpers.createTestInstance();
+        mgr = new MenuManager(
+                features,
+                testSearchManager,
+                state,
+                dirDetails,
+                activity,
+                selectionManager,
+                this::getApplicationNameFromAuthority,
+                this::getUriFromModelId);
+
+        selectionDetails.canViewInOwner = true;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeViewInOwner.assertInvisible();
+    }
+
+    @Test
     public void testActionMenu_changeToCanDelete() {
         selectionDetails.canDelete = false;
         mgr.updateActionMenu(testMenu, selectionDetails);
@@ -388,6 +417,8 @@
         optionAdvanced.assertTitle(R.string.menu_advanced_show);
         optionCreateDir.assertDisabled();
         optionDebug.assertInvisible();
+        optionSort.assertEnabled();
+        optionSort.assertVisible();
         assertTrue(testSearchManager.updateMenuCalled());
     }
 
@@ -543,8 +574,7 @@
     public void testContextMenu_OnFile() {
         selectionDetails.size = 1;
         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
-        dirOpen.assertVisible();
-        dirOpen.assertEnabled();
+        dirOpen.assertInvisible();
         dirCutToClipboard.assertVisible();
         dirCopyToClipboard.assertVisible();
         dirRename.assertVisible();
@@ -572,8 +602,7 @@
     public void testContextMenu_OnMultipleFiles() {
         selectionDetails.size = 3;
         mgr.updateContextMenuForFiles(testMenu, selectionDetails);
-        dirOpen.assertVisible();
-        dirOpen.assertDisabled();
+        dirOpen.assertInvisible();
     }
 
     @Test
diff --git a/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java b/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java
index ad87726..4679ee8 100644
--- a/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java
+++ b/tests/unit/com/android/documentsui/files/QuickViewIntentBuilderTest.java
@@ -6,13 +6,16 @@
 import android.content.Intent;
 import android.content.QuickViewConstants;
 import android.content.pm.PackageManager;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.testing.TestEnv;
 import com.android.documentsui.testing.TestPackageManager;
 import com.android.documentsui.testing.TestResources;
 
+import androidx.test.InstrumentationRegistry;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -25,23 +28,27 @@
 @RunWith(AndroidJUnit4.class)
 public class QuickViewIntentBuilderTest {
 
+    private static String mTargetPackageName;
     private PackageManager mPm;
     private TestEnv mEnv;
     private TestResources mRes;
 
     @Before
     public void setUp() {
+        mTargetPackageName =
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageName();
         mPm = TestPackageManager.create();
         mEnv = TestEnv.create();
         mRes = TestResources.create();
 
-        mRes.setQuickViewerPackage("com.android.documentsui");
+        mRes.setQuickViewerPackage(mTargetPackageName);
     }
 
     @Test
     public void testSetsNoFeatures_InArchiveDocument() {
         QuickViewIntentBuilder builder =
-                new QuickViewIntentBuilder(mPm, mRes, TestEnv.FILE_IN_ARCHIVE, mEnv.archiveModel);
+                new QuickViewIntentBuilder(
+                        mPm, mRes, TestEnv.FILE_IN_ARCHIVE, mEnv.archiveModel, false);
 
         Intent intent = builder.build();
 
@@ -52,7 +59,7 @@
     @Test
     public void testSetsFullFeatures_RegularDocument() {
         QuickViewIntentBuilder builder =
-                new QuickViewIntentBuilder(mPm, mRes, TestEnv.FILE_JPG, mEnv.model);
+                new QuickViewIntentBuilder(mPm, mRes, TestEnv.FILE_JPG, mEnv.model, false);
 
         Intent intent = builder.build();
 
@@ -67,4 +74,19 @@
         assertTrue(features.contains(QuickViewConstants.FEATURE_DOWNLOAD));
         assertTrue(features.contains(QuickViewConstants.FEATURE_PRINT));
     }
+
+    @Test
+    public void testPickerFeatures_RegularDocument() {
+
+        QuickViewIntentBuilder builder =
+                new QuickViewIntentBuilder(mPm, mRes, TestEnv.FILE_JPG, mEnv.model, true);
+
+        Intent intent = builder.build();
+
+        Set<String> features = new HashSet<>(
+                Arrays.asList(intent.getStringArrayExtra(Intent.EXTRA_QUICK_VIEW_FEATURES)));
+
+        assertEquals("Unexpected features set: " + features, 1, features.size());
+        assertTrue(features.contains(QuickViewConstants.FEATURE_VIEW));
+    }
 }
diff --git a/tests/unit/com/android/documentsui/inspector/DocumentLoaderPerfTest.java b/tests/unit/com/android/documentsui/inspector/DocumentLoaderPerfTest.java
new file mode 100644
index 0000000..10b53cb
--- /dev/null
+++ b/tests/unit/com/android/documentsui/inspector/DocumentLoaderPerfTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 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.documentsui.inspector;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
+import org.junit.Before;
+
+/**
+ * This test just like DocumentLoaderTest except that this test runs in real context environment.
+ */
+@LargeTest
+public class DocumentLoaderPerfTest extends DocumentLoaderTest {
+    @Override
+    protected Context prepareContentResolverSource() {
+        return InstrumentationRegistry.getTargetContext();
+    }
+}
diff --git a/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java b/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java
index cd487b6..9d9d63b 100644
--- a/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java
+++ b/tests/unit/com/android/documentsui/inspector/DocumentLoaderTest.java
@@ -15,25 +15,34 @@
  */
 package com.android.documentsui.inspector;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.ContentResolver;
 import android.content.Context;
+import android.media.ExifInterface;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Looper;
 import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
-import android.support.test.InstrumentationRegistry;
-import com.android.documentsui.InspectorProvider;
 import android.test.suitebuilder.annotation.MediumTest;
+
+import androidx.test.rule.provider.ProviderTestRule;
+
+import com.android.documentsui.InspectorProvider;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.inspector.InspectorController.DataSupplier;
-import com.android.documentsui.testing.TestLoaderManager;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
+import com.android.documentsui.testing.LatchedConsumer;
+import com.android.documentsui.testing.TestSupportLoaderManager;
+
 import junit.framework.TestCase;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * This test relies the inspector providers test.txt file in inspector root.
  */
@@ -45,16 +54,21 @@
     private static final String NOT_DIRECTORY = "OpenInProviderTest";
 
     private Context mContext;
-    private TestLoaderManager mLoaderManager;
+    private TestSupportLoaderManager mLoaderManager;
     private DataSupplier mLoader;
     private ContentResolver mResolver;
 
+    @Rule
+    private ProviderTestRule mProviderTestRule = new ProviderTestRule.Builder(
+            InspectorProvider.class, InspectorProvider.AUTHORITY).build();
+
     @Before
     public void setUp() throws Exception {
         super.setUp();
-        mContext = InstrumentationRegistry.getTargetContext();
+
+        mContext = prepareContentResolverSource();
         mResolver = mContext.getContentResolver();
-        mLoaderManager = new TestLoaderManager();
+        mLoaderManager = new TestSupportLoaderManager();
         mLoader = new RuntimeDataSupplier(mContext, mLoaderManager);
 
         if (Looper.myLooper() == null) {
@@ -62,6 +76,18 @@
         }
     }
 
+    protected Context prepareContentResolverSource() {
+        ContentResolver contentResolver = mProviderTestRule.getResolver();
+        Context context = mock(Context.class);
+        // inject ContentResolver
+        when(context.getContentResolver()).thenReturn(contentResolver);
+        // inject ContentResolver and prevent CursorLoader.loadInBackground from
+        // NullPointerException
+        when(context.getApplicationContext()).thenReturn(context);
+        return context;
+
+    }
+
     /**
      * Tests the loader using the Inspector Content provider. This test that we got valid info back
      * from the loader.
@@ -72,17 +98,17 @@
     public void testLoadsDocument() throws Exception {
         Uri validUri = DocumentsContract.buildDocumentUri(
                 InspectorProvider.AUTHORITY, TEST_DOC_NAME);
-        TestDocConsumer consumer = new TestDocConsumer(1);
+        LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1);
         mLoader.loadDocInfo(validUri, consumer);
 
         // this is a test double that requires explicitly loading. @see TestLoaderManager
         mLoaderManager.getLoader(0).startLoading();
 
-        consumer.latch.await(1000, TimeUnit.MILLISECONDS);
+        consumer.assertCalled(1000, TimeUnit.MILLISECONDS);
 
-        assertNotNull(consumer.info);
-        assertEquals(consumer.info.displayName, TEST_DOC_NAME);
-        assertEquals(consumer.info.size, 0);
+        assertNotNull(consumer.getValue());
+        assertEquals(consumer.getValue().displayName, TEST_DOC_NAME);
+        assertEquals(consumer.getValue().size, 0);
     }
 
     /**
@@ -93,21 +119,21 @@
     @Test
     public void testInvalidInput() throws Exception {
         Uri invalidUri = Uri.parse("content://poodles/chuckleberry/ham");
-        TestDocConsumer consumer = new TestDocConsumer(1);
+        LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1);
         mLoader.loadDocInfo(invalidUri, consumer);
 
         // this is a test double that requires explicitly loading. @see TestLoaderManager
         mLoaderManager.getLoader(0).startLoading();
 
-        consumer.latch.await(1000, TimeUnit.MILLISECONDS);
-        assertNull(consumer.info);
+        consumer.assertCalled(1000, TimeUnit.MILLISECONDS);
+        assertNull(consumer.getValue());
     }
 
     @Test
     public void testNonContentUri() {
 
         Uri invalidUri = Uri.parse("http://poodles/chuckleberry/ham");
-        TestDocConsumer consumer = new TestDocConsumer(1);
+        LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1);
 
         try {
             mLoader.loadDocInfo(invalidUri, consumer);
@@ -125,12 +151,12 @@
 
         DocumentInfo info = DocumentInfo.fromUri(mResolver, dirUri);
 
-        TestDirConsumer consumer = new TestDirConsumer(1);
+        LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1);
         mLoader.loadDirCount(info, consumer);
         mLoaderManager.getLoader(0).startLoading();
 
-        consumer.latch.await(1000, TimeUnit.MILLISECONDS);
-        assertEquals(consumer.childCount, 4);
+        consumer.assertCalled(1000, TimeUnit.MILLISECONDS);
+        assertEquals(consumer.getValue().intValue(), 4);
     }
 
     @Test
@@ -139,7 +165,7 @@
             InspectorProvider.AUTHORITY, NOT_DIRECTORY);
 
         DocumentInfo info = DocumentInfo.fromUri(mResolver, uri);
-        TestDirConsumer consumer = new TestDirConsumer(1);
+        LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1);
 
         try {
             mLoader.loadDirCount(info, consumer);
@@ -148,39 +174,33 @@
         } catch (Exception expected) {}
     }
 
-    /**
-     * Helper function for testing async processes.
-     */
-    private static class TestDocConsumer implements Consumer<DocumentInfo> {
+    @Test
+    public void testLoadMetadata() throws Exception  {
+        Uri uri = DocumentsContract.buildDocumentUri(
+                InspectorProvider.AUTHORITY, InspectorProvider.TEST_JPEG);
+        LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1);
 
-        private DocumentInfo info;
-        private CountDownLatch latch;
+        mLoader.getDocumentMetadata(uri, consumer);
+        mLoaderManager.getLoader(0).startLoading();
 
-        public TestDocConsumer(int expectedCount) {
-            latch = new CountDownLatch(expectedCount);
-        }
-
-        @Nullable
-        @Override
-        public void accept(DocumentInfo documentInfo) {
-            info = documentInfo;
-            latch.countDown();
-        }
+        consumer.assertCalled(100, TimeUnit.MILLISECONDS);
+        assertNotNull(consumer.getValue());
+        assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_WIDTH),
+                InspectorProvider.TEST_JPEG_WIDTH);
+        assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_LENGTH),
+                InspectorProvider.TEST_JPEG_HEIGHT);
     }
 
-    private static class TestDirConsumer implements Consumer<Integer> {
+    @Test
+    public void testLoadMetadata_Unsupported() throws Exception  {
+        Uri uri = DocumentsContract.buildDocumentUri(
+                InspectorProvider.AUTHORITY, InspectorProvider.INVALID_JPEG);
+        LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1);
 
-        private int childCount;
-        private CountDownLatch latch;
+        mLoader.getDocumentMetadata(uri, consumer);
+        mLoaderManager.getLoader(0).startLoading();
 
-        public TestDirConsumer(int expectedCount) {
-            latch = new CountDownLatch(expectedCount);
-        }
-
-        @Override
-        public void accept(Integer integer) {
-            childCount = integer;
-            latch.countDown();
-        }
+        consumer.assertCalled(100, TimeUnit.MILLISECONDS);
+        assertNull(consumer.getValue());
     }
-}
\ No newline at end of file
+}
diff --git a/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java b/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java
index 8610ea7..e25d227 100644
--- a/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java
+++ b/tests/unit/com/android/documentsui/inspector/GpsCoordinatesTextClassifierTest.java
@@ -17,17 +17,19 @@
 
 import static junit.framework.Assert.assertEquals;
 
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.LocaleList;
-import android.support.test.InstrumentationRegistry;
-
-import android.content.Context;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.textclassifier.TextClassification;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassifier;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.testing.TestPackageManager;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,8 +48,21 @@
         PackageManager pm = TestPackageManager.create();
         Context context = InstrumentationRegistry.getTargetContext();
 
-        TextClassifier defaultClassifier =
-                context.getSystemService(TextClassificationManager.class).getTextClassifier();
+        // The test case assertClassifiedGeo("-90.1, -180.156754", false) failed when full test,
+        // but it can pass "atest DocumentsUITests". Which means there might have some corruption
+        // when running whole test process.
+        // If someone run test case on TextClassificationManager but forgot to reset classifier
+        // back to default while teardown, such as cts/TextClassificationManagerTest.java, other
+        // test case might be effected. There are two ways to fix this test case, one is to fix
+        // at setup method with API setTextClassifier(null), this can ensure our test case is
+        // running with default classifier, i.e. systemTextClassifier. Another way is to find all
+        // test case which should clean their textClassifier object back to default while teardown,
+        // but this would be difficult to maintain than previous method.
+        TextClassificationManager manager =
+                context.getSystemService(TextClassificationManager.class);
+        // Reset classifier to default
+        manager.setTextClassifier(null);
+        TextClassifier defaultClassifier = manager.getTextClassifier();
         mClassifier = new GpsCoordinatesTextClassifier(pm, defaultClassifier);
     }
 
@@ -78,10 +93,9 @@
         assertClassifiedGeo("GeoIntent", false);
         assertClassifiedGeo("A.B, C.D", false);
         assertClassifiedGeo("90.165464, 180.1", false);
-        // TODO: Failing tests below
-        // assertClassifiedGeo("-90.1, -180.156754", false);
-        // assertClassifiedGeo("5000, 5000", false);
-        // assertClassifiedGeo("500, 500", false);
+        assertClassifiedGeo("-90.1, -180.156754", false);
+        assertClassifiedGeo("5000, 5000", false);
+        assertClassifiedGeo("500, 500", false);
     }
 
     private void assertClassifiedGeo(CharSequence text, boolean expectClassified) {
diff --git a/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java b/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java
index 58b533b..30178ce 100644
--- a/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java
+++ b/tests/unit/com/android/documentsui/inspector/HeaderTextSelectorTest.java
@@ -19,14 +19,16 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.widget.TextView;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.inspector.HeaderTextSelector.Selector;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java b/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java
index 8f70477..33693ed 100644
--- a/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java
+++ b/tests/unit/com/android/documentsui/inspector/InspectorControllerTest.java
@@ -15,7 +15,6 @@
  */
 package com.android.documentsui.inspector;
 
-import static junit.framework.Assert.fail;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
@@ -29,16 +28,16 @@
 import android.os.Looper;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View.OnClickListener;
 
+import androidx.annotation.Nullable;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.InspectorProvider;
 import com.android.documentsui.R;
 import com.android.documentsui.TestProviderActivity;
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.base.Shared;
 import com.android.documentsui.inspector.InspectorController.ActionDisplay;
 import com.android.documentsui.inspector.InspectorController.DataSupplier;
 import com.android.documentsui.inspector.InspectorController.DebugDisplay;
@@ -46,11 +45,9 @@
 import com.android.documentsui.inspector.InspectorController.HeaderDisplay;
 import com.android.documentsui.inspector.InspectorController.MediaDisplay;
 import com.android.documentsui.inspector.actions.Action;
-import com.android.documentsui.testing.TestConsumer;
 import com.android.documentsui.testing.TestEnv;
 import com.android.documentsui.testing.TestLoaderManager;
 import com.android.documentsui.testing.TestPackageManager;
-import com.android.documentsui.testing.TestPackageManager.TestResolveInfo;
 import com.android.documentsui.testing.TestProvidersAccess;
 
 import org.junit.Assert;
@@ -58,7 +55,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.function.Consumer;
 
 @RunWith(AndroidJUnit4.class)
@@ -80,7 +76,8 @@
     private TestAction mDefaultsTestDouble;
     private TestDebug mDebugTestDouble;
     private TestRunnable mErrCallback;
-    private Bundle mTestArgs;
+    private String mTitle;
+    private boolean mShowDebug;
 
     @Before
     public void setUp() throws Exception {
@@ -96,7 +93,8 @@
         mDefaultsTestDouble = new TestAction();
         mDebugTestDouble = new TestDebug();
         mErrCallback = new TestRunnable();
-        mTestArgs = new Bundle();
+        mTitle = "";
+        mShowDebug = false;
 
         // Add some fake data.
         mDataSupplier.mDoc = TestEnv.FILE_JPG;
@@ -123,7 +121,8 @@
                 mShowInProvider,
                 mDefaultsTestDouble,
                 mDebugTestDouble,
-                mTestArgs,
+                mTitle,
+                mShowDebug,
                 mErrCallback);
     }
 
@@ -142,7 +141,7 @@
      */
     @Test
     public void testShowDebugUpdatesView() throws Exception {
-        mTestArgs.putBoolean(Shared.EXTRA_SHOW_DEBUG, true);
+        mShowDebug = true;
         recreateController();
         mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
         mDebugTestDouble.assertVisible(true);
@@ -154,10 +153,10 @@
      */
     @Test
     public void testExtraTitleOverridesDisplayName() throws Exception {
-        mTestArgs.putString(Intent.EXTRA_TITLE, "hammy!");
+        mTitle = "hammy!";
         recreateController();
         mController.loadInfo(TestEnv.FILE_JPG.derivedUri);  // actual URI doesn't matter :)
-        mHeaderTestDouble.assertTitle("hammy!");
+        mDetailsTestDouble.assertTitle("hammy!");
     }
 
     /**
@@ -223,41 +222,6 @@
     }
 
     /**
-     * Test that the action clear app defaults is visible when conditions are met.
-     * @throws Exception
-     */
-    @Test
-    public void testAppDefaults_visible() throws Exception {
-        mPm.queryIntentProvidersResults = new ArrayList<>();
-        mPm.queryIntentProvidersResults.add(new TestResolveInfo());
-        mPm.queryIntentProvidersResults.add(new TestResolveInfo());
-        DocumentInfo doc = new DocumentInfo();
-        doc.derivedUri =
-            DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, OPEN_IN_PROVIDER_DOC);
-
-        mDataSupplier.mDoc = doc;
-        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
-        assertTrue(mDefaultsTestDouble.becameVisible);
-    }
-
-    /**
-     * Test that action clear app defaults is invisible when conditions have not been met.
-     * @throws Exception
-     */
-    @Test
-    public void testAppDefaults_invisible() throws Exception {
-        mPm.queryIntentProvidersResults = new ArrayList<>();
-        mPm.queryIntentProvidersResults.add(new TestResolveInfo());
-        DocumentInfo doc = new DocumentInfo();
-        doc.derivedUri =
-            DocumentsContract.buildDocumentUri(InspectorProvider.AUTHORITY, OPEN_IN_PROVIDER_DOC);
-
-        mDataSupplier.mDoc = doc;
-        mController.loadInfo(doc.derivedUri);  // actual URI doesn't matter :)
-        assertFalse(mDefaultsTestDouble.becameVisible);
-    }
-
-    /**
      * Test that update view will handle a null value properly. It uses a runnable to verify that
      * the static method Snackbars.showInspectorError(Activity activity) is called.
      *
@@ -371,16 +335,10 @@
     private static class TestHeader implements HeaderDisplay {
 
         private boolean mCalled = false;
-        private @Nullable String mTitle;
 
         @Override
-        public void accept(DocumentInfo info, String displayName) {
+        public void accept(DocumentInfo info) {
             mCalled = true;
-            mTitle = displayName;
-        }
-
-        public void assertTitle(String expected) {
-            Assert.assertEquals(expected, mTitle);
         }
 
         public void assertCalled() {
@@ -395,10 +353,16 @@
     private static class TestDetails implements DetailsDisplay {
 
         private boolean mCalled = false;
+        private @Nullable String mTitle;
 
         @Override
-        public void accept(DocumentInfo info) {
+        public void accept(DocumentInfo info, String displayName) {
             mCalled = true;
+            mTitle = displayName;
+        }
+
+        public void assertTitle(String expected) {
+            Assert.assertEquals(expected, mTitle);
         }
 
         @Override
@@ -480,4 +444,4 @@
             assertTrue(mCalled);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/unit/com/android/documentsui/inspector/MediaViewTest.java b/tests/unit/com/android/documentsui/inspector/MediaViewTest.java
index 7cf7b21..80c3c47 100644
--- a/tests/unit/com/android/documentsui/inspector/MediaViewTest.java
+++ b/tests/unit/com/android/documentsui/inspector/MediaViewTest.java
@@ -19,9 +19,10 @@
 import android.media.MediaMetadata;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.R;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.testing.TestEnv;
diff --git a/tests/unit/com/android/documentsui/overlay/OverlayableTest.java b/tests/unit/com/android/documentsui/overlay/OverlayableTest.java
new file mode 100644
index 0000000..17d437e
--- /dev/null
+++ b/tests/unit/com/android/documentsui/overlay/OverlayableTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 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.documentsui.overlay;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.drawable.Drawable;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.R;
+import com.android.documentsui.ui.ThemeUiTestBase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * This class verify overlayable resource defined in RRO package
+ * Verify Drawable, Dimen, Config to guarantee run time get resource without NotFound exception
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class OverlayableTest extends ThemeUiTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Test
+    public void testConfig_isLauncherEnable_isNotNull() {
+        assertThat(
+                mTargetContext.getResources().getBoolean(R.bool.is_launcher_enabled)).isNotNull();
+    }
+
+    @Test
+    public void testConfig_defaultRootUri_isNotEmpty() {
+        assertThat(
+                mTargetContext.getResources().getString(R.string.default_root_uri)).isNotEmpty();
+    }
+
+    @Test
+    public void testConfig_preferredRootPackage_isNotNull() {
+        assertThat(
+                mTargetContext.getResources().getString(
+                        R.string.preferred_root_package)).isNotNull();
+    }
+
+    @Test
+    public void testConfig_trustedQuickViewerPackage_isNotNull() {
+        assertThat(
+                mTargetContext.getResources().getString(
+                        R.string.trusted_quick_viewer_package)).isNotNull();
+    }
+
+    @Test
+    public void testDrawable_icEject_isVectorDrawable() {
+        assertThat(
+                mTargetContext.getResources().getDrawable(
+                        R.drawable.ic_eject)).isInstanceOf(Drawable.class);
+    }
+
+    @Test
+    public void testDrawable_icRootDownload_isVectorDrawable() {
+        assertThat(
+                mTargetContext.getResources().getDrawable(
+                        R.drawable.ic_root_download)).isInstanceOf(Drawable.class);
+    }
+
+    @Test
+    public void testDrawable_icSdStorage_isVectorDrawable() {
+        assertThat(
+                mTargetContext.getResources().getDrawable(
+                        R.drawable.ic_sd_storage)).isInstanceOf(Drawable.class);
+    }
+
+    @Test
+    public void testDrawable_icRootListSelector_isDrawable() {
+        assertThat(
+                mTargetContext.getResources().getDrawable(
+                        R.drawable.root_list_selector)).isInstanceOf(Drawable.class);
+    }
+
+    @Test
+    public void testDimen_gridItemRadius_isReasonable() {
+        int MAX_RADIUS = 160;
+        assertThat(
+                mTargetContext.getResources().getDimensionPixelSize(
+                        R.dimen.grid_item_radius)).isLessThan(MAX_RADIUS);
+        assertThat(
+                mTargetContext.getResources().getDimensionPixelSize(
+                        R.dimen.grid_item_radius)).isAtLeast(0);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
index 5d41565..0d07061 100644
--- a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java
@@ -16,10 +16,10 @@
 
 package com.android.documentsui.picker;
 
-import static junit.framework.Assert.assertTrue;
-
+import static org.mockito.Mockito.verify;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
 
 import android.app.Activity;
 import android.content.ClipData;
@@ -28,22 +28,31 @@
 import android.os.AsyncTask;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Path;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.AbstractActionHandler;
+import com.android.documentsui.DocumentsAccess;
+import com.android.documentsui.Injector;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentStack;
+import com.android.documentsui.base.Lookup;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
 import com.android.documentsui.base.State.ActionType;
+import com.android.documentsui.picker.ActionHandler.Addons;
+import com.android.documentsui.queries.SearchViewManager;
+import com.android.documentsui.roots.ProvidersAccess;
 import com.android.documentsui.testing.DocumentStackAsserts;
 import com.android.documentsui.testing.TestEnv;
-import com.android.documentsui.testing.TestProvidersAccess;
 import com.android.documentsui.testing.TestLastAccessedStorage;
+import com.android.documentsui.testing.TestProvidersAccess;
 import com.android.documentsui.testing.TestResolveInfo;
 
+import java.util.concurrent.Executor;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
@@ -57,17 +66,20 @@
 
     private TestEnv mEnv;
     private TestActivity mActivity;
-    private ActionHandler<TestActivity> mHandler;
+    private TestableActionHandler<TestActivity> mHandler;
     private TestLastAccessedStorage mLastAccessed;
+    private PickCountRecordStorage mPickCountRecord;
 
     @Before
     public void setUp() {
         mEnv = TestEnv.create();
         mActivity = TestActivity.create(mEnv);
         mEnv.providers.configurePm(mActivity.packageMgr);
+        mEnv.injector.pickResult = new PickResult();
         mLastAccessed = new TestLastAccessedStorage();
+        mPickCountRecord = mock(PickCountRecordStorage.class);
 
-        mHandler = new ActionHandler<>(
+        mHandler = new TestableActionHandler<>(
                 mActivity,
                 mEnv.state,
                 mEnv.providers,
@@ -75,7 +87,8 @@
                 mEnv.searchViewManager,
                 mEnv::lookupExecutor,
                 mEnv.injector,
-                mLastAccessed
+                mLastAccessed,
+                mPickCountRecord
         );
 
         mEnv.dialogs.confirmNext();
@@ -85,6 +98,32 @@
         AsyncTask.setDefaultExecutor(mEnv.mExecutor);
     }
 
+    private static class TestableActionHandler<T extends FragmentActivity & Addons>
+        extends ActionHandler {
+
+        private UpdatePickResultTask mTask;
+
+        TestableActionHandler(
+            T activity,
+            State state,
+            ProvidersAccess providers,
+            DocumentsAccess docs,
+            SearchViewManager searchMgr,
+            Lookup<String, Executor> executors,
+            Injector injector,
+            LastAccessedStorage lastAccessed,
+            PickCountRecordStorage pickCountRecordStorage) {
+            super(activity, state, providers, docs, searchMgr, executors, injector, lastAccessed);
+            mTask = new UpdatePickResultTask(
+                mActivity, mInjector.pickResult, pickCountRecordStorage);
+        }
+
+        @Override
+        public UpdatePickResultTask getUpdatePickResultTask() {
+            return mTask;
+        }
+    }
+
     @AfterClass
     public static void tearDownOnce() {
         AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -181,20 +220,13 @@
     }
 
     @Test
-    public void testInitLocation_DefaultToRecents_ActionOpenTree() throws Exception {
-        testInitLocationDefaultToRecentsOnAction(State.ACTION_OPEN_TREE);
+    public void testInitLocation_DefaultToDownloads_ActionOpenTree() throws Exception {
+        testInitLocationDefaultToDownloadsOnAction(State.ACTION_OPEN_TREE);
     }
 
     @Test
     public void testInitLocation_DefaultsToDownloads_ActionCreate() throws Exception {
-        mEnv.state.action = State.ACTION_CREATE;
-        mActivity.resources.bools.put(R.bool.show_documents_root, false);
-
-        mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
-
-        mHandler.initLocation(mActivity.getIntent());
-
-        assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
+        testInitLocationDefaultToDownloadsOnAction(State.ACTION_CREATE);
     }
 
     @Test
@@ -207,6 +239,23 @@
     }
 
     @Test
+    public void testIncreasePickCountRecordCalled() throws Exception {
+        mEnv.state.action = State.ACTION_GET_CONTENT;
+        mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
+        mEnv.state.stack.push(TestEnv.FOLDER_1);
+
+        mActivity.finishedHandler.assertNotCalled();
+        mHandler.finishPicking(TestEnv.FILE_JPG.derivedUri);
+
+        mEnv.beforeAsserts();
+
+        verify(mPickCountRecord).increasePickCountRecord(
+            mActivity.getApplicationContext(), TestEnv.FILE_JPG.derivedUri);
+
+        mActivity.finishedHandler.assertCalled();
+    }
+
+    @Test
     public void testPickDocument_SetsCorrectResultAndFinishes_ActionPickCopyDestination()
             throws Exception {
 
@@ -217,7 +266,7 @@
 
         mActivity.finishedHandler.assertNotCalled();
 
-        mHandler.pickDocument(TestEnv.FOLDER_2);
+        mHandler.pickDocument(null, TestEnv.FOLDER_2);
 
         mEnv.beforeAsserts();
 
@@ -243,7 +292,9 @@
 
         mActivity.finishedHandler.assertNotCalled();
 
-        mHandler.pickDocument(TestEnv.FOLDER_2);
+        Uri uri = DocumentsContract.buildTreeDocumentUri(
+                TestEnv.FOLDER_2.authority, TestEnv.FOLDER_2.documentId);
+        mHandler.finishPicking(uri);
 
         mEnv.beforeAsserts();
 
@@ -306,6 +357,16 @@
     }
 
     @Test
+    public void testPickDocument_ConfirmsOpenTree() {
+        mEnv.state.action = State.ACTION_OPEN_TREE;
+        mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
+
+        mHandler.pickDocument(null, TestEnv.FOLDER_1);
+
+        mEnv.dialogs.assertDocumentTreeConfirmed(TestEnv.FOLDER_1);
+    }
+
+    @Test
     public void testFinishPicking_SetsCorrectResultAndFinishes_ActionGetContent() throws Exception {
         mEnv.state.action = State.ACTION_GET_CONTENT;
         mEnv.state.stack.changeRoot(TestProvidersAccess.HOME);
@@ -466,6 +527,25 @@
         assertNotNull(mActivity.startActivityForResult.getLastValue().first);
     }
 
+    @Test
+    public void testOpenAppRootWithQueryContent_matchedContent() throws Exception {
+        final String queryContent = "query";
+        mActivity.intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryContent);
+        mHandler.openRoot(TestResolveInfo.create());
+        assertEquals(queryContent,
+                mActivity.startActivityForResult.getLastValue().first.getStringExtra(
+                        Intent.EXTRA_CONTENT_QUERY));
+    }
+
+    @Test
+    public void testPreviewItem() throws Exception {
+        mActivity.resources.setQuickViewerPackage("corptropolis.viewer");
+        mActivity.currentRoot = TestProvidersAccess.HOME;
+
+        mHandler.priviewDocument(TestEnv.FILE_GIF);
+        mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW);
+    }
+
     private void testInitLocationDefaultToRecentsOnAction(@ActionType int action)
             throws Exception {
         mEnv.state.action = action;
@@ -479,6 +559,20 @@
         mActivity.refreshCurrentRootAndDirectory.assertCalled();
     }
 
+    private void testInitLocationDefaultToDownloadsOnAction(@ActionType int action)
+            throws Exception {
+        mEnv.state.action = action;
+        mActivity.resources.bools.put(R.bool.show_documents_root, false);
+        mActivity.resources.strings.put(R.string.default_root_uri,
+                TestProvidersAccess.DOWNLOADS.getUri().toString());
+
+        mActivity.refreshCurrentRootAndDirectory.assertNotCalled();
+
+        mHandler.initLocation(mActivity.getIntent());
+
+        assertRootPicked(TestProvidersAccess.DOWNLOADS.getUri());
+    }
+
     private void assertRootPicked(Uri expectedUri) throws Exception {
         mEnv.beforeAsserts();
 
diff --git a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java
index d457f67..8287e9f 100644
--- a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java
+++ b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java
@@ -17,19 +17,28 @@
 package com.android.documentsui.picker;
 
 import static com.android.documentsui.base.State.ACTION_CREATE;
+import static com.android.documentsui.base.State.ACTION_GET_CONTENT;
 import static com.android.documentsui.base.State.ACTION_OPEN;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.database.MatrixCursor;
+import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.DirectoryResult;
+import com.android.documentsui.Model;
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.base.State;
+import com.android.documentsui.roots.RootCursorWrapper;
 import com.android.documentsui.testing.TestDirectoryDetails;
+import com.android.documentsui.testing.TestFeatures;
 import com.android.documentsui.testing.TestMenu;
 import com.android.documentsui.testing.TestMenuItem;
 import com.android.documentsui.testing.TestSearchViewManager;
@@ -69,6 +78,7 @@
     /* Action Mode menu items */
     private TestMenuItem actionModeOpen;
     private TestMenuItem actionModeOpenWith;
+    private TestMenuItem actionModeSelect;
     private TestMenuItem actionModeShare;
     private TestMenuItem actionModeDelete;
     private TestMenuItem actionModeSelectAll;
@@ -78,17 +88,20 @@
     private TestMenuItem actionModeCompress;
     private TestMenuItem actionModeRename;
     private TestMenuItem actionModeViewInOwner;
+    private TestMenuItem actionModeSort;
 
     /* Option Menu items */
     private TestMenuItem optionSearch;
     private TestMenuItem optionDebug;
-    private TestMenuItem optionGrid;
-    private TestMenuItem optionList;
     private TestMenuItem optionNewWindow;
     private TestMenuItem optionCreateDir;
     private TestMenuItem optionSelectAll;
     private TestMenuItem optionAdvanced;
     private TestMenuItem optionSettings;
+    private TestMenuItem optionSort;
+
+    private TestMenuItem subOptionGrid;
+    private TestMenuItem subOptionList;
 
     private TestSelectionDetails selectionDetails;
     private TestDirectoryDetails dirDetails;
@@ -120,8 +133,8 @@
         rootPasteIntoFolder = testMenu.findItem(R.id.root_menu_paste_into_folder);
         rootSettings = testMenu.findItem(R.id.root_menu_settings);
 
-        actionModeOpen = testMenu.findItem(R.id.action_menu_open);
         actionModeOpenWith = testMenu.findItem(R.id.action_menu_open_with);
+        actionModeSelect = testMenu.findItem(R.id.action_menu_select);
         actionModeShare = testMenu.findItem(R.id.action_menu_share);
         actionModeDelete = testMenu.findItem(R.id.action_menu_delete);
         actionModeSelectAll = testMenu.findItem(R.id.action_menu_select_all);
@@ -131,16 +144,20 @@
         actionModeCompress = testMenu.findItem(R.id.action_menu_compress);
         actionModeRename = testMenu.findItem(R.id.action_menu_rename);
         actionModeViewInOwner = testMenu.findItem(R.id.action_menu_view_in_owner);
+        actionModeSort = testMenu.findItem(R.id.action_menu_sort);
 
         optionSearch = testMenu.findItem(R.id.option_menu_search);
         optionDebug = testMenu.findItem(R.id.option_menu_debug);
-        optionGrid = testMenu.findItem(R.id.option_menu_grid);
-        optionList = testMenu.findItem(R.id.option_menu_list);
         optionNewWindow = testMenu.findItem(R.id.option_menu_new_window);
         optionCreateDir = testMenu.findItem(R.id.option_menu_create_dir);
         optionSelectAll = testMenu.findItem(R.id.option_menu_select_all);
         optionAdvanced = testMenu.findItem(R.id.option_menu_advanced);
         optionSettings = testMenu.findItem(R.id.option_menu_settings);
+        optionSort = testMenu.findItem(R.id.option_menu_sort);
+
+        // Menu actions on root title row.
+        subOptionGrid = testMenu.findItem(R.id.sub_menu_grid);
+        subOptionList = testMenu.findItem(R.id.sub_menu_list);
 
         selectionDetails = new TestSelectionDetails();
         dirDetails = new TestDirectoryDetails();
@@ -156,23 +173,47 @@
     @Test
     public void testActionMenu() {
         mgr.updateActionMenu(testMenu, selectionDetails);
-
-        actionModeOpen.assertInvisible();
+        actionModeSelect.assertInvisible();
         actionModeDelete.assertInvisible();
         actionModeShare.assertInvisible();
         actionModeRename.assertInvisible();
         actionModeSelectAll.assertVisible();
         actionModeViewInOwner.assertInvisible();
+        actionModeSort.assertVisible();
+        actionModeSort.assertEnabled();
     }
 
     @Test
-    public void testActionMenu_openAction() {
+    public void testActionMenu_selectAction() {
         state.action = ACTION_OPEN;
         mgr.updateActionMenu(testMenu, selectionDetails);
 
-        actionModeOpen.assertVisible();
+        actionModeSelect.assertVisible();
     }
 
+    @Test
+    public void testActionMenu_selectActionTitle() {
+        state.action = ACTION_OPEN;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeSelect.assertTitle(R.string.menu_select);
+    }
+
+    @Test
+    public void testActionMenu_getContentAction() {
+        state.action = ACTION_GET_CONTENT;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeSelect.assertVisible();
+    }
+
+    @Test
+    public void testActionMenu_getContentActionTitle() {
+        state.action = ACTION_GET_CONTENT;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeSelect.assertTitle(R.string.menu_select);
+    }
 
     @Test
     public void testActionMenu_notAllowMultiple() {
@@ -183,12 +224,22 @@
     }
 
     @Test
+    public void testActionMenu_AllowMultiple() {
+        state.allowMultiple = true;
+        mgr.updateActionMenu(testMenu, selectionDetails);
+
+        actionModeSelectAll.assertVisible();
+    }
+
+    @Test
     public void testOptionMenu() {
         mgr.updateOptionMenu(testMenu);
 
         optionAdvanced.assertInvisible();
         optionAdvanced.assertTitle(R.string.menu_advanced_show);
         optionCreateDir.assertDisabled();
+        optionSort.assertEnabled();
+        optionSort.assertVisible();
         assertTrue(testSearchManager.showMenuCalled());
     }
 
@@ -197,10 +248,11 @@
         state.action = ACTION_OPEN;
         state.derivedMode = State.MODE_LIST;
         mgr.updateOptionMenu(testMenu);
+        mgr.updateSubMenu(testMenu);
 
         optionCreateDir.assertInvisible();
-        optionGrid.assertVisible();
-        optionList.assertInvisible();
+        subOptionGrid.assertVisible();
+        subOptionList.assertInvisible();
         assertFalse(testSearchManager.showMenuCalled());
     }
 
@@ -226,9 +278,31 @@
     public void testOptionMenu_inRecents() {
         dirDetails.isInRecents = true;
         mgr.updateOptionMenu(testMenu);
+        mgr.updateSubMenu(testMenu);
 
-        optionGrid.assertInvisible();
-        optionList.assertInvisible();
+        subOptionGrid.assertInvisible();
+        subOptionList.assertInvisible();
+    }
+
+
+    @Test
+    public void testOptionMenu_onlyContainer() {
+        state.allowMultiple = true;
+        mgr.updateModel(getTestModel(true));
+        mgr.updateOptionMenu(testMenu);
+
+        optionSelectAll.assertVisible();
+        optionSelectAll.assertDisabled();
+    }
+
+    @Test
+    public void testOptionMenu_containerAndFile() {
+        state.allowMultiple = true;
+        mgr.updateModel(getTestModel(false));
+        mgr.updateOptionMenu(testMenu);
+
+        optionSelectAll.assertVisible();
+        optionSelectAll.assertEnabled();
     }
 
     @Test
@@ -418,4 +492,35 @@
 
         rootEjectRoot.assertInvisible();
     }
+
+    private Model getTestModel(boolean onlyDirectory) {
+        String[] COLUMNS = new String[]{
+                RootCursorWrapper.COLUMN_AUTHORITY,
+                Document.COLUMN_DOCUMENT_ID,
+                Document.COLUMN_FLAGS,
+                Document.COLUMN_DISPLAY_NAME,
+                Document.COLUMN_SIZE,
+                Document.COLUMN_LAST_MODIFIED,
+                Document.COLUMN_MIME_TYPE
+        };
+        MatrixCursor c = new MatrixCursor(COLUMNS);
+        for (int i = 0; i < 3; ++i) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
+            row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
+        }
+
+        if (!onlyDirectory) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(Document.COLUMN_DOCUMENT_ID, "4");
+            row.add(Document.COLUMN_MIME_TYPE, "image/jpg");
+        }
+
+        DirectoryResult r = new DirectoryResult();
+        r.cursor = c;
+        Model model = new Model(new TestFeatures());
+        model.update(r);
+
+        return model;
+    }
 }
diff --git a/tests/unit/com/android/documentsui/picker/PickCountRecordProviderTest.java b/tests/unit/com/android/documentsui/picker/PickCountRecordProviderTest.java
new file mode 100644
index 0000000..05cbe38
--- /dev/null
+++ b/tests/unit/com/android/documentsui/picker/PickCountRecordProviderTest.java
@@ -0,0 +1,89 @@
+package com.android.documentsui.picker;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+import androidx.test.rule.provider.ProviderTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class PickCountRecordProviderTest {
+
+    private final static int FAKE_FILE_ID = 1234567;
+
+    private Uri mPickRecordUri;
+
+    @Rule
+    public ProviderTestRule mProviderTestRule = new ProviderTestRule.Builder(
+            PickCountRecordProvider.class, PickCountRecordProvider.AUTHORITY)
+            .build();
+
+    @Before
+    public void setUp() {
+        mPickRecordUri = PickCountRecordProvider.buildPickRecordUri(FAKE_FILE_ID);
+        final ContentValues values = new ContentValues();
+        values.clear();
+        values.put(PickCountRecordProvider.Columns.PICK_COUNT, 1);
+        mProviderTestRule.getResolver().insert(mPickRecordUri, values);
+    }
+
+    @After
+    public void tearDown() {
+        mProviderTestRule.getResolver().delete(mPickRecordUri, null, null);
+    }
+
+    @Test
+    public void testInsert() {
+        final ContentValues values = new ContentValues();
+        values.clear();
+        values.put(PickCountRecordProvider.Columns.PICK_COUNT, 3);
+        mProviderTestRule.getResolver().insert(mPickRecordUri, values);
+        Cursor cursor = mProviderTestRule.getResolver().query(
+            mPickRecordUri, null, null, null, null);
+        cursor.moveToNext();
+        int index = cursor.getColumnIndex(PickCountRecordProvider.Columns.PICK_COUNT);
+        assertThat(cursor.getInt(index)).isEqualTo(3);
+    }
+
+    @Test
+    public void testQuery() {
+        Cursor cursor = mProviderTestRule.getResolver().query(
+            mPickRecordUri, null, null, null, null);
+        cursor.moveToNext();
+        int index = cursor.getColumnIndex(PickCountRecordProvider.Columns.PICK_COUNT);
+        assertThat(cursor.getInt(index)).isEqualTo(1);
+    }
+
+    @Test
+    public void testDelete() {
+        Cursor cursor = mProviderTestRule.getResolver().query(
+            mPickRecordUri, null, null, null, null);
+        assertThat(cursor.getCount()).isEqualTo(1);
+
+        mProviderTestRule.getResolver().delete(mPickRecordUri, null, null);
+
+        cursor = mProviderTestRule.getResolver().query(
+            mPickRecordUri, null, null, null, null);
+        assertThat(cursor.getCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testUpdate() {
+        boolean unsupportExcetionCaught = false;
+        try {
+            mProviderTestRule.getResolver().update(mPickRecordUri, null, null, null);
+        } catch (UnsupportedOperationException e) {
+            unsupportExcetionCaught = true;
+        }
+        assertThat(unsupportExcetionCaught).isTrue();
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/picker/PickResultTest.java b/tests/unit/com/android/documentsui/picker/PickResultTest.java
new file mode 100644
index 0000000..62a7956
--- /dev/null
+++ b/tests/unit/com/android/documentsui/picker/PickResultTest.java
@@ -0,0 +1,71 @@
+package com.android.documentsui.picker;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.Uri;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class PickResultTest {
+    private PickResult mPickResult;
+
+    @Before
+    public void setUp() {
+        mPickResult = new PickResult();
+    }
+
+    @Test
+    public void testActionCount() {
+        mPickResult.increaseActionCount();
+        assertThat(mPickResult.getActionCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void testDuration() {
+        mPickResult.setPickStartTime(487);
+        mPickResult.increaseDuration(9487);
+        assertThat(mPickResult.getDuration()).isEqualTo(9000);
+    }
+
+    @Test
+    public void testFileCount() {
+        mPickResult.setFileCount(10);
+        assertThat(mPickResult.getFileCount()).isEqualTo(10);
+    }
+
+    @Test
+    public void testIsSearching() {
+        mPickResult.setIsSearching(true);
+        assertThat(mPickResult.isSearching()).isTrue();
+    }
+
+    @Test
+    public void testRoot() {
+        mPickResult.setRoot(2);
+        assertThat(mPickResult.getRoot()).isEqualTo(2);
+    }
+
+    @Test
+    public void testMimeType() {
+        mPickResult.setMimeType(3);
+        assertThat(mPickResult.getMimeType()).isEqualTo(3);
+    }
+
+    @Test
+    public void testRepeatedlyPickTimes() {
+        mPickResult.setRepeatedPickTimes(4);
+        assertThat(mPickResult.getRepeatedPickTimes()).isEqualTo(4);
+    }
+
+    @Test
+    public void testFileUri() {
+        Uri fakeUri = new Uri.Builder().authority("test").appendPath("path").build();
+        mPickResult.setFileUri(fakeUri);
+        assertThat(mPickResult.getFileUri()).isEqualTo(fakeUri);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/picker/TestActivity.java b/tests/unit/com/android/documentsui/picker/TestActivity.java
index 2a7b6be..50942cc 100644
--- a/tests/unit/com/android/documentsui/picker/TestActivity.java
+++ b/tests/unit/com/android/documentsui/picker/TestActivity.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.picker;
 
-import android.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 import android.content.Intent;
 import android.util.Pair;
 
diff --git a/tests/unit/com/android/documentsui/prefs/PreferencesMonitorTest.java b/tests/unit/com/android/documentsui/prefs/PreferencesMonitorTest.java
index 7332513..1ff3464 100644
--- a/tests/unit/com/android/documentsui/prefs/PreferencesMonitorTest.java
+++ b/tests/unit/com/android/documentsui/prefs/PreferencesMonitorTest.java
@@ -17,9 +17,10 @@
 package com.android.documentsui.prefs;
 
 import android.content.SharedPreferences;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.testing.TestConsumer;
 
diff --git a/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java b/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java
index 3c421c3..08c72c5 100644
--- a/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java
+++ b/tests/unit/com/android/documentsui/prefs/PrefsBackupHelperTest.java
@@ -18,24 +18,23 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
-import java.util.Map;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 @RunWith(AndroidJUnit4.class)
diff --git a/tests/unit/com/android/documentsui/queries/CommandInterceptorTest.java b/tests/unit/com/android/documentsui/queries/CommandInterceptorTest.java
index ca68ff7..4598318 100644
--- a/tests/unit/com/android/documentsui/queries/CommandInterceptorTest.java
+++ b/tests/unit/com/android/documentsui/queries/CommandInterceptorTest.java
@@ -18,8 +18,8 @@
 
 import static com.android.documentsui.queries.CommandInterceptor.COMMAND_PREFIX;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.testing.TestEventHandler;
 import com.android.documentsui.testing.TestFeatures;
diff --git a/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java b/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java
new file mode 100644
index 0000000..03b7358
--- /dev/null
+++ b/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2018 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.documentsui.queries;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.R;
+import com.android.documentsui.base.MimeTypes;
+import com.android.documentsui.base.Shared;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class SearchChipViewManagerTest {
+
+    private static final String[] TEST_MIME_TYPES = new String[]{"image/*", "video/*"};
+    private static int CHIP_TYPE = 1000;
+
+    private Context mContext;
+    private SearchChipViewManager mSearchChipViewManager;
+    private LinearLayout mChipGroup;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        mContext.setTheme(com.android.documentsui.R.style.DocumentsTheme);
+        mContext.getTheme().applyStyle(R.style.DocumentsDefaultTheme, false);
+        mChipGroup = spy(new LinearLayout(mContext));
+
+        mSearchChipViewManager = new SearchChipViewManager(mChipGroup);
+        mSearchChipViewManager.initChipSets(new String[] {"*/*"});
+    }
+
+    @Test
+    public void testInitChipSets_HasCorrectValue() throws Exception {
+        mSearchChipViewManager.initChipSets(TEST_MIME_TYPES);
+        mSearchChipViewManager.updateChips(new String[] {"*/*"});
+
+        assertThat(mChipGroup.getChildCount()).isEqualTo(TEST_MIME_TYPES.length);
+    }
+
+    @Test
+    public void testUpdateChips_HasCorrectValue() throws Exception {
+        mSearchChipViewManager.updateChips(TEST_MIME_TYPES);
+
+        assertThat(mChipGroup.getChildCount()).isEqualTo(TEST_MIME_TYPES.length);
+    }
+
+    @Test
+    public void testGetCheckedChipMimeTypes_HasCorrectValue() throws Exception {
+        mSearchChipViewManager.mCheckedChipItems = getFakeSearchChipDataList();
+
+        final String[] checkedMimeTypes = mSearchChipViewManager.getCheckedMimeTypes();
+
+        assertThat(MimeTypes.mimeMatches(TEST_MIME_TYPES, checkedMimeTypes[0])).isTrue();
+        assertThat(MimeTypes.mimeMatches(TEST_MIME_TYPES, checkedMimeTypes[1])).isTrue();
+    }
+
+    @Test
+    public void testRestoreCheckedChipItems_HasCorrectValue() throws Exception {
+        Bundle bundle = new Bundle();
+        bundle.putIntArray(Shared.EXTRA_QUERY_CHIPS, new int[]{2});
+
+        mSearchChipViewManager.restoreCheckedChipItems(bundle);
+
+        assertThat(mSearchChipViewManager.mCheckedChipItems.size()).isEqualTo(1);
+        Iterator<SearchChipData> iterator = mSearchChipViewManager.mCheckedChipItems.iterator();
+        assertThat(iterator.next().getChipType()).isEqualTo(2);
+    }
+
+    @Test
+    public void testSaveInstanceState_HasCorrectValue() throws Exception {
+        mSearchChipViewManager.mCheckedChipItems = getFakeSearchChipDataList();
+        Bundle bundle = new Bundle();
+
+        mSearchChipViewManager.onSaveInstanceState(bundle);
+
+        final int[] chipTypes = bundle.getIntArray(Shared.EXTRA_QUERY_CHIPS);
+        assertThat(chipTypes.length).isEqualTo(1);
+        assertThat(chipTypes[0]).isEqualTo(CHIP_TYPE);
+    }
+
+    @Test
+    public void testBindMirrorGroup_sameValue() throws Exception {
+        mSearchChipViewManager.updateChips(new String[] {"*/*"});
+
+        ViewGroup mirror = spy(new LinearLayout(mContext));
+        mSearchChipViewManager.bindMirrorGroup(mirror);
+
+        assertThat(View.VISIBLE).isEqualTo(mirror.getVisibility());
+        assertThat(mChipGroup.getChildCount()).isEqualTo(mirror.getChildCount());
+        assertThat(mChipGroup.getChildAt(0).getTag()).isEqualTo(mirror.getChildAt(0).getTag());
+    }
+
+    @Test
+    public void testBindMirrorGroup_hideRow() throws Exception {
+        mSearchChipViewManager.updateChips(new String[] {"image/*"});
+
+        ViewGroup mirror = spy(new LinearLayout(mContext));
+        mSearchChipViewManager.bindMirrorGroup(mirror);
+
+        assertThat(View.GONE).isEqualTo(mirror.getVisibility());
+    }
+
+    private static Set<SearchChipData> getFakeSearchChipDataList() {
+        final Set<SearchChipData> chipDataList = new HashSet<>();
+        chipDataList.add(new SearchChipData(CHIP_TYPE, 0, TEST_MIME_TYPES));
+        return chipDataList;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/queries/SearchHistoryManagerTest.java b/tests/unit/com/android/documentsui/queries/SearchHistoryManagerTest.java
new file mode 100644
index 0000000..1f2a974
--- /dev/null
+++ b/tests/unit/com/android/documentsui/queries/SearchHistoryManagerTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 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.documentsui.queries;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.queries.SearchHistoryManager;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public final class SearchHistoryManagerTest {
+
+    private Context mContext;
+    private CountDownLatch mLatch ;
+    private SearchHistoryManager mManager;
+    private SearchHistoryManager.DatabaseChangedListener mListener;
+    private int mIntResult;
+    private long mLongResult;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mManager = SearchHistoryManager.getInstance(mContext);
+        clearData();
+        mIntResult = -1;
+        mLongResult = -1;
+    }
+
+    @After
+    public void tearDown() {
+        mListener = null;
+        clearData();
+    }
+
+    private void clearData() {
+        final List<String> list = mManager.getHistoryList(null);
+        for (int i = 0; i < list.size(); i++) {
+            mManager.deleteHistory(list.get(i));
+        }
+    }
+
+    @Test
+    public void testAddHistory() throws Exception {
+        mLatch = new CountDownLatch(2);
+        mListener = new SearchHistoryManager.DatabaseChangedListener() {
+            @Override
+            public void onAddChangedListener(long longResult) {
+                mLongResult = longResult;
+                mLatch.countDown();
+            }
+            @Override
+            public void onDeleteChangedListener(int intResult) { }
+            @Override
+            public void onPostExecute() { }
+
+            };
+        mManager.setDatabaseListener(mListener);
+        mManager.addHistory("testKeyword");
+        mLatch.await(1, TimeUnit.SECONDS);
+
+        assertThat(mLongResult).isGreaterThan(0L);
+    }
+
+    @Test
+    public void testDeleteHistory() throws Exception {
+        mLatch = new CountDownLatch(2);
+        mListener = new SearchHistoryManager.DatabaseChangedListener() {
+            @Override
+            public void onAddChangedListener(long longResult) {
+                mLongResult = longResult;
+                mLatch.countDown();
+            }
+            @Override
+            public void onPostExecute() { }
+
+            @Override public void onDeleteChangedListener(int intResult) {
+                mIntResult = intResult;
+                mLatch.countDown();
+            }
+        };
+        mManager.setDatabaseListener(mListener);
+
+        mManager.addHistory("testDeleteKeyword");
+        mLatch.await(1, TimeUnit.SECONDS);
+        assertThat(mLongResult).isGreaterThan(0L);
+
+        // TODO: Solving this tricky usage of new CountDownLatch(2) count with bg/127610355
+        // Using this tricky way is for making sure the result synchronization of public APIs
+        // getHistoryList()/addHistory()/deleteHistory() with database processing.
+        // From design contract and non-blocking UI design, not necessarily doing synchronization
+        // from code level, therefore doing this tricky usage of new CountDownLatch in test case for
+        // guarantee the synchronization.
+        mLatch = new CountDownLatch(2);
+        mManager.deleteHistory("testDeleteKeyword");
+        mLatch.await(1, TimeUnit.SECONDS);
+        assertThat(mIntResult).isGreaterThan(0);
+    }
+
+    @Test
+    public void testGetHistoryList() throws Exception {
+        mLatch = new CountDownLatch(2);
+        mListener = new SearchHistoryManager.DatabaseChangedListener() {
+            @Override
+            public void onAddChangedListener(long longResult) { }
+            @Override
+            public void onDeleteChangedListener(int intResult) { }
+            @Override
+            public void onPostExecute() {
+                mLatch.countDown();
+            }
+        };
+        mManager.setDatabaseListener(mListener);
+
+        mManager.addHistory("abcdefghijk");
+        mLatch.await(1, TimeUnit.SECONDS);
+
+        mLatch = new CountDownLatch(2);
+        mManager.addHistory("lmnop");
+        mLatch.await(1, TimeUnit.SECONDS);
+
+        mLatch = new CountDownLatch(2);
+        mManager.addHistory("qrstuv");
+        mLatch.await(1, TimeUnit.SECONDS);
+
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        assertThat(mManager.getHistoryList(null).size()).isEqualTo(3);
+
+        // Test the last adding history should be the first item in the list.
+        assertThat(mManager.getHistoryList(null).get(0)).contains("qrstuv");
+
+        assertThat(mManager.getHistoryList(null).get(2)).contains("abcdefghijk");
+    }
+}
diff --git a/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java b/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java
index feffaec..c4be9f3 100644
--- a/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java
+++ b/tests/unit/com/android/documentsui/queries/SearchViewManagerTest.java
@@ -16,34 +16,54 @@
 
 package com.android.documentsui.queries;
 
+import static android.provider.DocumentsContract.QUERY_ARG_DISPLAY_NAME;
+import static android.provider.DocumentsContract.QUERY_ARG_FILE_SIZE_OVER;
+import static android.provider.DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER;
+import static android.provider.DocumentsContract.QUERY_ARG_MIME_TYPES;
+import static android.provider.DocumentsContract.Root.FLAG_SUPPORTS_SEARCH;
+
+import static com.android.documentsui.base.State.ACTION_GET_CONTENT;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
 
-import android.annotation.Nullable;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
+import android.provider.DocumentsContract;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.annotation.Nullable;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.R;
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.EventHandler;
+import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.queries.SearchViewManager.SearchManagerListener;
-import com.android.documentsui.queries.SearchViewManager;
 import com.android.documentsui.testing.TestEventHandler;
 import com.android.documentsui.testing.TestHandler;
 import com.android.documentsui.testing.TestMenu;
+import com.android.documentsui.testing.TestMenuItem;
 import com.android.documentsui.testing.TestTimer;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.HashSet;
+import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -54,7 +74,10 @@
     private TestEventHandler<String> mTestEventHandler;
     private TestTimer mTestTimer;
     private TestHandler mTestHandler;
-    private SearchViewManager mSearchViewManager;
+    private TestMenu mTestMenu;
+    private TestMenuItem mSearchMenuItem;
+    private TestableSearchViewManager mSearchViewManager;
+    private SearchChipViewManager mSearchChipViewManager;
 
     private boolean mListenerOnSearchChangedCalled;
 
@@ -69,27 +92,50 @@
             public void onSearchChanged(@Nullable String query) {
                 mListenerOnSearchChangedCalled = true;
             }
+
             @Override
-            public void onSearchFinished() {}
+            public void onSearchFinished() {
+            }
+
             @Override
-            public void onSearchViewChanged(boolean opened) {}
+            public void onSearchViewChanged(boolean opened) {
+            }
+
+            @Override
+            public void onSearchChipStateChanged(View v) {
+            }
+
+            @Override
+            public void onSearchViewFocusChanged(boolean hasFocus) {
+            }
+
+            @Override
+            public void onSearchViewClearClicked() {
+            }
         };
 
-        mSearchViewManager = new TestableSearchViewManager(
-                searchListener, mTestEventHandler, null, mTestTimer, mTestHandler);
+        ViewGroup chipGroup = mock(ViewGroup.class);
+        mSearchChipViewManager = spy(new SearchChipViewManager(chipGroup));
+        mSearchViewManager = new TestableSearchViewManager(searchListener, mTestEventHandler,
+                mSearchChipViewManager, null /* savedState */, mTestTimer, mTestHandler);
 
-        final TestMenu testMenu = TestMenu.create();
-        mSearchViewManager.install(testMenu, true);
+        mTestMenu = TestMenu.create();
+        mSearchMenuItem = mTestMenu.findItem(R.id.option_menu_search);
+        mSearchViewManager.install(mTestMenu, true, false);
     }
 
     private static class TestableSearchViewManager extends SearchViewManager {
+
+        private String mHistoryRecorded;
+
         public TestableSearchViewManager(
                 SearchManagerListener listener,
                 EventHandler<String> commandProcessor,
+                SearchChipViewManager chipViewManager,
                 @Nullable Bundle savedState,
                 Timer timer,
                 Handler handler) {
-            super(listener, commandProcessor, savedState, timer, handler);
+            super(listener, commandProcessor, chipViewManager, savedState, timer, handler);
         }
 
         @Override
@@ -98,6 +144,15 @@
             TestTimer.Task testTask = new TestTimer.Task(task);
             return testTask;
         }
+
+        @Override
+        public void recordHistory() {
+            mHistoryRecorded = getCurrentSearch();
+        }
+
+        public String getRecordedHistory() {
+            return mHistoryRecorded;
+        }
     }
 
     private void fastForwardTo(long timeMs) {
@@ -105,6 +160,27 @@
         mTestHandler.dispatchAllMessages();
     }
 
+
+    @Test
+    public void testParseQueryContent_ActionIsNotMatched_NotParseQueryContent() {
+        final String queryString = "query";
+        Intent intent = new Intent();
+        intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryString);
+
+        mSearchViewManager.parseQueryContentFromIntent(intent, -1);
+        assertTrue(mSearchViewManager.getQueryContentFromIntent() == null);
+    }
+
+    @Test
+    public void testParseQueryContent_queryContentIsMatched() {
+        final String queryString = "query";
+        Intent intent = new Intent();
+        intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryString);
+
+        mSearchViewManager.parseQueryContentFromIntent(intent, ACTION_GET_CONTENT);
+        assertEquals(queryString, mSearchViewManager.getQueryContentFromIntent());
+    }
+
     @Test
     public void testIsExpanded_ExpandsOnClick() {
         mSearchViewManager.onClick(null);
@@ -119,6 +195,12 @@
     }
 
     @Test
+    public void testIsSearching_TrueHasCheckedChip() throws Exception {
+        mSearchChipViewManager.mCheckedChipItems = getFakeSearchChipDataList();
+        assertTrue(mSearchViewManager.isSearching());
+    }
+
+    @Test
     public void testIsSearching_FalseOnClick() throws Exception {
         mSearchViewManager.onClick(null);
         assertFalse(mSearchViewManager.isSearching());
@@ -220,4 +302,109 @@
         mSearchViewManager.onQueryTextSubmit("q");
         assertFalse(mListenerOnSearchChangedCalled);
     }
+
+    @Test
+    public void testHistoryRecorded_recordOnQueryTextSubmit() {
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextSubmit("q");
+
+        assertEquals(mSearchViewManager.getCurrentSearch(),
+                mSearchViewManager.getRecordedHistory());
+    }
+
+    @Test
+    public void testCheckedChipItems_IsEmptyIfSearchCanceled() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchChipViewManager.mCheckedChipItems = getFakeSearchChipDataList();
+        mSearchViewManager.cancelSearch();
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+        assertTrue(!mSearchChipViewManager.hasCheckedItems());
+    }
+
+    @Test
+    public void testBuildQueryArgs_hasSearchString() throws Exception {
+        final String query = "q";
+        mSearchViewManager.onClick(null);
+        mSearchViewManager.onQueryTextChange("q");
+        fastForwardTo(SearchViewManager.SEARCH_DELAY_MS);
+
+        final Bundle queryArgs = mSearchViewManager.buildQueryArgs();
+        assertFalse(queryArgs.isEmpty());
+
+        final String queryString = queryArgs.getString(DocumentsContract.QUERY_ARG_DISPLAY_NAME);
+        assertEquals(query, queryString);
+    }
+
+    @Test
+    public void testBuildQueryArgs_hasMimeType() throws Exception {
+        mSearchViewManager.onClick(null);
+        mSearchChipViewManager.mCheckedChipItems = getFakeSearchChipDataList();
+
+        final Bundle queryArgs = mSearchViewManager.buildQueryArgs();
+        assertFalse(queryArgs.isEmpty());
+
+        final String[] mimeTypes = queryArgs.getStringArray(QUERY_ARG_MIME_TYPES);
+        assertTrue(mimeTypes.length > 0);
+        assertEquals("image/*", mimeTypes[0]);
+    }
+
+    @Test
+    public void testSupportsMimeTypesSearch_showChips() throws Exception {
+        RootInfo root = spy(new RootInfo());
+        when(root.isRecents()).thenReturn(false);
+        root.flags = FLAG_SUPPORTS_SEARCH;
+        root.queryArgs = QUERY_ARG_MIME_TYPES;
+        DocumentStack stack = new DocumentStack(root, new DocumentInfo());
+
+        mSearchViewManager.showMenu(stack);
+
+        verify(mSearchChipViewManager, times(1)).setChipsRowVisible(true);
+    }
+
+    @Test
+    public void testNotSupportsMimeTypesSearch_notShowChips() throws Exception {
+        RootInfo root = spy(new RootInfo());
+        when(root.isRecents()).thenReturn(false);
+        root.flags = FLAG_SUPPORTS_SEARCH;
+        root.queryArgs = TextUtils.join("\n",
+                new String[]{QUERY_ARG_DISPLAY_NAME, QUERY_ARG_FILE_SIZE_OVER,
+                        QUERY_ARG_LAST_MODIFIED_AFTER});
+        DocumentStack stack = new DocumentStack(root, new DocumentInfo());
+
+        mSearchViewManager.showMenu(stack);
+
+        verify(mSearchChipViewManager, times(1)).setChipsRowVisible(false);
+    }
+
+    @Test
+    public void testSupportsSearch_showMenu() throws Exception {
+        RootInfo root = spy(new RootInfo());
+        when(root.isRecents()).thenReturn(false);
+        root.flags = FLAG_SUPPORTS_SEARCH;
+        DocumentStack stack = new DocumentStack(root, new DocumentInfo());
+
+        mSearchViewManager.showMenu(stack);
+
+        assertTrue(mSearchMenuItem.isVisible());
+    }
+
+    @Test
+    public void testNotSupportsSearch_notShowMenuAndChips() throws Exception {
+        RootInfo root = spy(new RootInfo());
+        when(root.isRecents()).thenReturn(false);
+        root.queryArgs = QUERY_ARG_MIME_TYPES;
+        DocumentStack stack = new DocumentStack(root, new DocumentInfo());
+
+        mSearchViewManager.install(mTestMenu, true, false);
+        mSearchViewManager.showMenu(stack);
+
+        assertFalse(mSearchMenuItem.isVisible());
+        verify(mSearchChipViewManager, times(1)).setChipsRowVisible(false);
+    }
+
+    private static Set<SearchChipData> getFakeSearchChipDataList() {
+        final Set<SearchChipData> chipDataList = new HashSet<>();
+        chipDataList.add(new SearchChipData(0 /* chipType */, 0, new String[]{"image/*"}));
+        return chipDataList;
+    }
 }
diff --git a/tests/unit/com/android/documentsui/roots/ProvidersCacheTest.java b/tests/unit/com/android/documentsui/roots/ProvidersAccessTest.java
similarity index 98%
rename from tests/unit/com/android/documentsui/roots/ProvidersCacheTest.java
rename to tests/unit/com/android/documentsui/roots/ProvidersAccessTest.java
index b8a6422..d2022a6 100644
--- a/tests/unit/com/android/documentsui/roots/ProvidersCacheTest.java
+++ b/tests/unit/com/android/documentsui/roots/ProvidersAccessTest.java
@@ -30,7 +30,7 @@
 import java.util.List;
 
 @SmallTest
-public class ProvidersCacheTest extends AndroidTestCase {
+public class ProvidersAccessTest extends AndroidTestCase {
 
     private static RootInfo mNull = new RootInfo();
     private static RootInfo mEmpty = buildForMimeTypes();
diff --git a/tests/unit/com/android/documentsui/selection/BandSelectionHelperTest.java b/tests/unit/com/android/documentsui/selection/BandSelectionHelperTest.java
deleted file mode 100644
index 87b7a1d..0000000
--- a/tests/unit/com/android/documentsui/selection/BandSelectionHelperTest.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView.OnScrollListener;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.BandSelectionHelper.BandHost;
-import com.android.documentsui.selection.testing.SelectionPredicates;
-import com.android.documentsui.selection.testing.TestAdapter;
-import com.android.documentsui.selection.testing.TestBandPredicate;
-import com.android.documentsui.selection.testing.TestEvents.Builder;
-import com.android.documentsui.selection.testing.TestStableIdProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Collections;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class BandSelectionHelperTest {
-
-    private List<String> mItems;
-    private BandSelectionHelper mBandController;
-    private boolean mIsActive;
-    private Builder mStartBuilder;
-    private Builder mStopBuilder;
-    private MotionEvent mStartEvent;
-    private MotionEvent mStopEvent;
-    private TestBandHost mBandHost;
-    private TestBandPredicate mBandPredicate;
-
-    @Before
-    public void setup() throws Exception {
-        mItems = TestAdapter.createItemList(10);
-        mIsActive = false;
-        TestAdapter adapter = new TestAdapter();
-        adapter.updateTestModelIds(mItems);
-        mBandHost = new TestBandHost();
-        mBandPredicate = new TestBandPredicate();
-
-        SelectionHelper helper = new DefaultSelectionHelper(
-                DefaultSelectionHelper.MODE_SINGLE,
-                adapter,
-                new TestStableIdProvider(adapter),
-                SelectionPredicates.CAN_SET_ANYTHING);
-
-        mBandController = new BandSelectionHelper(
-                mBandHost,
-                adapter,
-                new TestStableIdProvider(adapter),
-                helper,
-                SelectionPredicates.CAN_SET_ANYTHING,
-                mBandPredicate,
-                new ContentLock()) {
-                    @Override
-                    public boolean isActive() {
-                        return mIsActive;
-                    }
-                };
-
-        mStartBuilder = new Builder().mouse().primary().action(MotionEvent.ACTION_MOVE);
-        mStopBuilder = new Builder().mouse().action(MotionEvent.ACTION_UP);
-        mStartEvent = mStartBuilder.build();
-        mStopEvent = mStopBuilder.build();
-    }
-
-    @Test
-    public void testGoodStart() {
-        assertTrue(mBandController.shouldStart(mStartEvent));
-    }
-
-    @Test
-    public void testBadStart_NoButtons() {
-        assertFalse(mBandController.shouldStart(
-                mStartBuilder.releaseButton(MotionEvent.BUTTON_PRIMARY).build()));
-    }
-
-    @Test
-    public void testBadStart_SecondaryButton() {
-        assertFalse(
-                mBandController.shouldStart(mStartBuilder.secondary().build()));
-    }
-
-    @Test
-    public void testBadStart_TertiaryButton() {
-        assertFalse(
-                mBandController.shouldStart(mStartBuilder.tertiary().build()));
-    }
-
-    @Test
-    public void testBadStart_Touch() {
-        assertFalse(mBandController.shouldStart(
-                mStartBuilder.touch().releaseButton(MotionEvent.BUTTON_PRIMARY).build()));
-    }
-
-    @Test
-    public void testBadStart_RespectsCanInitiateBand() {
-        mBandPredicate.setCanInitiate(false);
-        assertFalse(mBandController.shouldStart(mStartEvent));
-    }
-
-    @Test
-    public void testBadStart_ActionDown() {
-        assertFalse(mBandController
-                .shouldStart(mStartBuilder.action(MotionEvent.ACTION_DOWN).build()));
-    }
-
-    @Test
-    public void testBadStart_ActionUp() {
-        assertFalse(mBandController
-                .shouldStart(mStartBuilder.action(MotionEvent.ACTION_UP).build()));
-    }
-
-    @Test
-    public void testBadStart_ActionPointerDown() {
-        assertFalse(mBandController.shouldStart(
-                mStartBuilder.action(MotionEvent.ACTION_POINTER_DOWN).build()));
-    }
-
-    @Test
-    public void testBadStart_ActionPointerUp() {
-        assertFalse(mBandController.shouldStart(
-                mStartBuilder.action(MotionEvent.ACTION_POINTER_UP).build()));
-    }
-
-    @Test
-    public void testBadStart_NoItems() {
-        TestAdapter emptyAdapter = new TestAdapter();
-        emptyAdapter.updateTestModelIds(Collections.EMPTY_LIST);
-
-        SelectionHelper helper = new DefaultSelectionHelper(
-                DefaultSelectionHelper.MODE_SINGLE,
-                emptyAdapter,
-                new TestStableIdProvider(emptyAdapter),
-                SelectionPredicates.CAN_SET_ANYTHING);
-
-        mBandController = new BandSelectionHelper(
-                new TestBandHost(),
-                emptyAdapter,
-                new TestStableIdProvider(emptyAdapter),
-                helper,
-                SelectionPredicates.CAN_SET_ANYTHING,
-                mBandPredicate,
-                new ContentLock());
-
-        assertFalse(mBandController.shouldStart(mStartEvent));
-    }
-
-    @Test
-    public void testBadStart_alreadyActive() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStart(mStartEvent));
-    }
-
-    @Test
-    public void testGoodStop() {
-        mIsActive = true;
-        assertTrue(mBandController.shouldStop(mStopEvent));
-    }
-
-    @Test
-    public void testGoodStop_PointerUp() {
-        mIsActive = true;
-        assertTrue(mBandController
-                .shouldStop(mStopBuilder.action(MotionEvent.ACTION_POINTER_UP).build()));
-    }
-
-    @Test
-    public void testGoodStop_Cancel() {
-        mIsActive = true;
-        assertTrue(mBandController
-                .shouldStop(mStopBuilder.action(MotionEvent.ACTION_CANCEL).build()));
-    }
-
-    @Test
-    public void testBadStop_NotActive() {
-        assertFalse(mBandController.shouldStop(mStopEvent));
-    }
-
-    @Test
-    public void testBadStop_NonMouse() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStop(mStopBuilder.touch().build()));
-    }
-
-    @Test
-    public void testBadStop_Move() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStop(
-                mStopBuilder.action(MotionEvent.ACTION_MOVE).touch().build()));
-    }
-
-    @Test
-    public void testBadStop_Down() {
-        mIsActive = true;
-        assertFalse(mBandController.shouldStop(
-                mStopBuilder.action(MotionEvent.ACTION_DOWN).touch().build()));
-    }
-
-    private final class TestBandHost extends BandHost {
-        @Override
-        public void scrollBy(int dy) {
-        }
-
-        @Override
-        public void runAtNextFrame(Runnable r) {
-        }
-
-        @Override
-        public void removeCallback(Runnable r) {
-        }
-
-        @Override
-        public void showBand(Rect rect) {
-        }
-
-        @Override
-        public void hideBand() {
-        }
-
-        @Override
-        public void addOnScrollListener(OnScrollListener listener) {
-        }
-
-        @Override
-        public void removeOnScrollListener(OnScrollListener listener) {
-        }
-
-        @Override
-        public int getHeight() {
-            return 0;
-        }
-
-        @Override
-        public void invalidateView() {
-        }
-
-        @Override
-        public Point createAbsolutePoint(Point relativePoint) {
-            return null;
-        }
-
-        @Override
-        public Rect getAbsoluteRectForChildViewAt(int index) {
-            return null;
-        }
-
-        @Override
-        public int getAdapterPositionAt(int index) {
-            return 0;
-        }
-
-        @Override
-        public int getColumnCount() {
-            return 0;
-        }
-
-        @Override
-        public int getChildCount() {
-            return 0;
-        }
-
-        @Override
-        public int getVisibleChildCount() {
-            return 0;
-        }
-
-        @Override
-        public boolean hasView(int adapterPosition) {
-            return false;
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/ContentLockTest.java b/tests/unit/com/android/documentsui/selection/ContentLockTest.java
deleted file mode 100644
index 71b6b0f..0000000
--- a/tests/unit/com/android/documentsui/selection/ContentLockTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ContentLockTest {
-
-    private ContentLock mLock = new ContentLock();
-    private boolean mCalled;
-
-    private Runnable mRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mCalled = true;
-        }
-    };
-
-    @Before
-    public void setUp() {
-        mCalled = false;
-    }
-
-    @Test
-    public void testNotBlocking_callbackNotBlocked() {
-        mLock.runWhenUnlocked(mRunnable);
-        assertTrue(mCalled);
-    }
-
-    @Test
-    public void testToggleBlocking_callbackNotBlocked() {
-        mLock.block();
-        mLock.unblock();
-        mLock.runWhenUnlocked(mRunnable);
-        assertTrue(mCalled);
-    }
-
-    @Test
-    public void testBlocking_callbackBlocked() {
-        mLock.block();
-        mLock.runWhenUnlocked(mRunnable);
-        assertFalse(mCalled);
-    }
-
-    @Test
-    public void testBlockthenUnblock_callbackNotBlocked() {
-        mLock.block();
-        mLock.runWhenUnlocked(mRunnable);
-        mLock.unblock();
-        assertTrue(mCalled);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/DefaultSelectionHelperTest.java b/tests/unit/com/android/documentsui/selection/DefaultSelectionHelperTest.java
deleted file mode 100644
index 48c0b2a..0000000
--- a/tests/unit/com/android/documentsui/selection/DefaultSelectionHelperTest.java
+++ /dev/null
@@ -1,409 +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.documentsui.selection;
-import static org.junit.Assert.assertFalse;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.SparseBooleanArray;
-
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestAdapter;
-import com.android.documentsui.selection.testing.TestSelectionObserver;
-import com.android.documentsui.selection.testing.TestStableIdProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DefaultSelectionHelperTest {
-
-    private List<String> mItems;
-    private Set<String> mIgnored;
-    private TestAdapter mAdapter;
-    private DefaultSelectionHelper mHelper;
-    private TestSelectionObserver mListener;
-    private SelectionProbe mSelection;
-
-    @Before
-    public void setUp() throws Exception {
-        mIgnored = new HashSet<>();
-        mItems = TestAdapter.createItemList(100);
-        mListener = new TestSelectionObserver();
-        mAdapter = new TestAdapter();
-        mAdapter.updateTestModelIds(mItems);
-
-        SelectionPredicate canSelect = new SelectionPredicate() {
-
-            @Override
-            public boolean canSetStateForId(String id, boolean nextState) {
-                return !nextState || !mIgnored.contains(id);
-            }
-
-            @Override
-            public boolean canSetStateAtPosition(int position, boolean nextState) {
-                throw new UnsupportedOperationException("Not implemented.");
-            }
-        };
-        mHelper = new DefaultSelectionHelper(
-                DefaultSelectionHelper.MODE_MULTIPLE,
-                mAdapter,
-                new TestStableIdProvider(mAdapter),
-                canSelect);
-
-        mHelper.addObserver(mListener);
-
-        mSelection = new SelectionProbe(mHelper, mListener);
-
-        mIgnored.clear();
-    }
-
-    @Test
-    public void testSelect() {
-        mHelper.select(mItems.get(7));
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testDeselect() {
-        mHelper.select(mItems.get(7));
-        mHelper.deselect(mItems.get(7));
-
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testSelection_DoNothingOnUnselectableItem() {
-        mIgnored.add(mItems.get(7));
-        boolean selected = mHelper.select(mItems.get(7));
-
-        assertFalse(selected);
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testSelect_NotifiesListenersOfChange() {
-        mHelper.select(mItems.get(7));
-
-        mListener.assertSelectionChanged();
-    }
-
-    @Test
-    public void testSelect_NotifiesAdapterOfSelect() {
-        mHelper.select(mItems.get(7));
-
-        mAdapter.assertNotifiedOfSelectionChange(7);
-    }
-
-    @Test
-    public void testSelect_NotifiesAdapterOfDeselect() {
-        mHelper.select(mItems.get(7));
-        mAdapter.resetSelectionNotifications();
-        mHelper.deselect(mItems.get(7));
-        mAdapter.assertNotifiedOfSelectionChange(7);
-    }
-
-    @Test
-    public void testDeselect_NotifiesSelectionChanged() {
-        mHelper.select(mItems.get(7));
-        mHelper.deselect(mItems.get(7));
-
-        mListener.assertSelectionChanged();
-    }
-
-    @Test
-    public void testSelection_PersistsOnUpdate() {
-        mHelper.select(mItems.get(7));
-        mAdapter.updateTestModelIds(mItems);
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testSelection_IntersectsWithNewDataSet() {
-        mHelper.select(mItems.get(99));
-        mHelper.select(mItems.get(7));
-
-        mAdapter.updateTestModelIds(TestAdapter.createItemList(50));
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testSetItemsSelected() {
-        mHelper.setItemsSelected(getStringIds(6, 7, 8), true);
-
-        mSelection.assertRangeSelected(6, 8);
-    }
-
-    @Test
-    public void testSetItemsSelected_SkipUnselectableItem() {
-        mIgnored.add(mItems.get(7));
-
-        mHelper.setItemsSelected(getStringIds(6, 7, 8), true);
-
-        mSelection.assertSelected(6);
-        mSelection.assertNotSelected(7);
-        mSelection.assertSelected(8);
-    }
-
-    @Test
-    public void testRangeSelection() {
-        mHelper.startRange(15);
-        mHelper.extendRange(19);
-        mSelection.assertRangeSelection(15, 19);
-    }
-
-    @Test
-    public void testRangeSelection_SkipUnselectableItem() {
-        mIgnored.add(mItems.get(17));
-
-        mHelper.startRange(15);
-        mHelper.extendRange(19);
-
-        mSelection.assertRangeSelected(15, 16);
-        mSelection.assertNotSelected(17);
-        mSelection.assertRangeSelected(18, 19);
-    }
-
-    @Test
-    public void testRangeSelection_snapExpand() {
-        mHelper.startRange(15);
-        mHelper.extendRange(19);
-        mHelper.extendRange(27);
-        mSelection.assertRangeSelection(15, 27);
-    }
-
-    @Test
-    public void testRangeSelection_snapContract() {
-        mHelper.startRange(15);
-        mHelper.extendRange(27);
-        mHelper.extendRange(19);
-        mSelection.assertRangeSelection(15, 19);
-    }
-
-    @Test
-    public void testRangeSelection_snapInvert() {
-        mHelper.startRange(15);
-        mHelper.extendRange(27);
-        mHelper.extendRange(3);
-        mSelection.assertRangeSelection(3, 15);
-    }
-
-    @Test
-    public void testRangeSelection_multiple() {
-        mHelper.startRange(15);
-        mHelper.extendRange(27);
-        mHelper.endRange();
-        mHelper.startRange(42);
-        mHelper.extendRange(57);
-        mSelection.assertSelectionSize(29);
-        mSelection.assertRangeSelected(15, 27);
-        mSelection.assertRangeSelected(42, 57);
-    }
-
-    @Test
-    public void testProvisionalRangeSelection() {
-        mHelper.startRange(13);
-        mHelper.extendProvisionalRange(15);
-        mSelection.assertRangeSelection(13, 15);
-        mHelper.getSelection().mergeProvisionalSelection();
-        mHelper.endRange();
-        mSelection.assertSelectionSize(3);
-    }
-
-    @Test
-    public void testProvisionalRangeSelection_endEarly() {
-        mHelper.startRange(13);
-        mHelper.extendProvisionalRange(15);
-        mSelection.assertRangeSelection(13, 15);
-
-        mHelper.endRange();
-        // If we end range selection prematurely for provision selection, nothing should be selected
-        // except the first item
-        mSelection.assertSelectionSize(1);
-    }
-
-    @Test
-    public void testProvisionalRangeSelection_snapExpand() {
-        mHelper.startRange(13);
-        mHelper.extendProvisionalRange(15);
-        mSelection.assertRangeSelection(13, 15);
-        mHelper.getSelection().mergeProvisionalSelection();
-        mHelper.extendRange(18);
-        mSelection.assertRangeSelection(13, 18);
-    }
-
-    @Test
-    public void testCombinationRangeSelection_IntersectsOldSelection() {
-        mHelper.startRange(13);
-        mHelper.extendRange(15);
-        mSelection.assertRangeSelection(13, 15);
-
-        mHelper.startRange(11);
-        mHelper.extendProvisionalRange(18);
-        mSelection.assertRangeSelected(11, 18);
-        mHelper.endRange();
-        mSelection.assertRangeSelected(13, 15);
-        mSelection.assertRangeSelected(11, 11);
-        mSelection.assertSelectionSize(4);
-    }
-
-    @Test
-    public void testProvisionalSelection() {
-        Selection s = mHelper.getSelection();
-        mSelection.assertNoSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mListener.onItemStateChanged(mItems.get(1), true);
-        mListener.onItemStateChanged(mItems.get(2), true);
-
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(1, 2);
-    }
-
-    @Test
-    public void testProvisionalSelection_Replace() {
-        Selection s = mHelper.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mListener.onItemStateChanged(mItems.get(1), true);
-        mListener.onItemStateChanged(mItems.get(2), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-
-        mListener.onItemStateChanged(mItems.get(1), false);
-        mListener.onItemStateChanged(mItems.get(2), false);
-        provisional.clear();
-
-        mListener.onItemStateChanged(mItems.get(3), true);
-        mListener.onItemStateChanged(mItems.get(4), true);
-        provisional.append(3, true);
-        provisional.append(4, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(3, 4);
-    }
-
-    @Test
-    public void testProvisionalSelection_IntersectsExistingProvisionalSelection() {
-        Selection s = mHelper.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mListener.onItemStateChanged(mItems.get(1), true);
-        mListener.onItemStateChanged(mItems.get(2), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-
-        mListener.onItemStateChanged(mItems.get(1), false);
-        mListener.onItemStateChanged(mItems.get(2), false);
-        provisional.clear();
-
-        mListener.onItemStateChanged(mItems.get(1), true);
-        provisional.append(1, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(1);
-    }
-
-    @Test
-    public void testProvisionalSelection_Apply() {
-        Selection s = mHelper.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mListener.onItemStateChanged(mItems.get(1), true);
-        mListener.onItemStateChanged(mItems.get(2), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(1, true);
-        provisional.append(2, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        s.mergeProvisionalSelection();
-
-        mSelection.assertSelection(1, 2);
-    }
-
-    @Test
-    public void testProvisionalSelection_Cancel() {
-        mHelper.select(mItems.get(1));
-        mHelper.select(mItems.get(2));
-        Selection s = mHelper.getSelection();
-
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(3, true);
-        provisional.append(4, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        s.clearProvisionalSelection();
-
-        // Original selection should remain.
-        mSelection.assertSelection(1, 2);
-    }
-
-    @Test
-    public void testProvisionalSelection_IntersectsAppliedSelection() {
-        mHelper.select(mItems.get(1));
-        mHelper.select(mItems.get(2));
-        Selection s = mHelper.getSelection();
-
-        // Mimicking band selection case -- BandController notifies item callback by itself.
-        mListener.onItemStateChanged(mItems.get(3), true);
-        SparseBooleanArray provisional = new SparseBooleanArray();
-        provisional.append(2, true);
-        provisional.append(3, true);
-        s.setProvisionalSelection(getItemIds(provisional));
-        mSelection.assertSelection(1, 2, 3);
-    }
-
-    @Test
-    public void testObserverOnChanged_NotifiesListenersOfChange() {
-        mAdapter.notifyDataSetChanged();
-
-        mListener.assertSelectionChanged();
-    }
-
-    private Set<String> getItemIds(SparseBooleanArray selection) {
-        Set<String> ids = new HashSet<>();
-
-        int count = selection.size();
-        for (int i = 0; i < count; ++i) {
-            ids.add(mItems.get(selection.keyAt(i)));
-        }
-
-        return ids;
-    }
-
-    private Iterable<String> getStringIds(int... ids) {
-        List<String> stringIds = new ArrayList<>(ids.length);
-        for (int id : ids) {
-            stringIds.add(mItems.get(id));
-        }
-        return stringIds;
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/DefaultSelectionHelper_SingleSelectTest.java b/tests/unit/com/android/documentsui/selection/DefaultSelectionHelper_SingleSelectTest.java
deleted file mode 100644
index 563ce87..0000000
--- a/tests/unit/com/android/documentsui/selection/DefaultSelectionHelper_SingleSelectTest.java
+++ /dev/null
@@ -1,84 +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.documentsui.selection;
-
-import static org.junit.Assert.fail;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.documentsui.selection.testing.SelectionPredicates;
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestAdapter;
-import com.android.documentsui.selection.testing.TestSelectionObserver;
-import com.android.documentsui.selection.testing.TestStableIdProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DefaultSelectionHelper_SingleSelectTest {
-
-    private List<String> mItems;
-    private SelectionHelper mHelper;
-    private TestSelectionObserver mListener;
-    private SelectionProbe mSelection;
-
-    @Before
-    public void setUp() throws Exception {
-        mItems = TestAdapter.createItemList(100);
-        mListener = new TestSelectionObserver();
-        TestAdapter adapter = new TestAdapter();
-        adapter.updateTestModelIds(mItems);
-
-        mHelper = new DefaultSelectionHelper(
-                DefaultSelectionHelper.MODE_SINGLE,
-                adapter,
-                new TestStableIdProvider(adapter),
-                SelectionPredicates.CAN_SET_ANYTHING);
-
-        mHelper.addObserver(mListener);
-
-        mSelection = new SelectionProbe(mHelper);
-    }
-
-    @Test
-    public void testSimpleSelect() {
-        mHelper.select(mItems.get(3));
-        mHelper.select(mItems.get(4));
-        mListener.assertSelectionChanged();
-        mSelection.assertSelection(4);
-    }
-
-    @Test
-    public void testRangeSelectionNotEstablished() {
-        mHelper.select(mItems.get(3));
-        mListener.reset();
-
-        try {
-            mHelper.extendRange(10);
-            fail("Should have thrown.");
-        } catch (Exception expected) {}
-
-        mListener.assertSelectionUnchanged();
-        mSelection.assertSelection(3);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/GestureRouterTest.java b/tests/unit/com/android/documentsui/selection/GestureRouterTest.java
deleted file mode 100644
index e467f0f..0000000
--- a/tests/unit/com/android/documentsui/selection/GestureRouterTest.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyFloat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.GestureDetector.OnDoubleTapListener;
-import android.view.GestureDetector.OnGestureListener;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.testing.TestEvents.Mouse;
-import com.android.documentsui.selection.testing.TestEvents.Touch;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class GestureRouterTest {
-
-    private TestHandler mHandler;
-    private TestHandler mAlt;
-    private GestureRouter<TestHandler> mRouter;
-
-    @Before
-    public void setUp() {
-        mAlt = new TestHandler();
-        mHandler = new TestHandler();
-    }
-
-    @Test
-    public void testDelegates() {
-        mRouter = new GestureRouter<>();
-        mRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mHandler);
-        mRouter.register(MotionEvent.TOOL_TYPE_FINGER, mAlt);
-
-        mRouter.onDown(Mouse.CLICK);
-        mHandler.assertCalled_onDown(Mouse.CLICK);
-        mAlt.assertNotCalled_onDown();
-
-        mRouter.onShowPress(Mouse.CLICK);
-        mHandler.assertCalled_onShowPress(Mouse.CLICK);
-        mAlt.assertNotCalled_onShowPress();
-
-        mRouter.onSingleTapUp(Mouse.CLICK);
-        mHandler.assertCalled_onSingleTapUp(Mouse.CLICK);
-        mAlt.assertNotCalled_onSingleTapUp();
-
-        mRouter.onScroll(null, Mouse.CLICK, -1, -1);
-        mHandler.assertCalled_onScroll(null, Mouse.CLICK, -1, -1);
-        mAlt.assertNotCalled_onScroll();
-
-        mRouter.onLongPress(Mouse.CLICK);
-        mHandler.assertCalled_onLongPress(Mouse.CLICK);
-        mAlt.assertNotCalled_onLongPress();
-
-        mRouter.onFling(null, Mouse.CLICK, -1, -1);
-        mHandler.assertCalled_onFling(null, Mouse.CLICK, -1, -1);
-        mAlt.assertNotCalled_onFling();
-
-        mRouter.onSingleTapConfirmed(Mouse.CLICK);
-        mHandler.assertCalled_onSingleTapConfirmed(Mouse.CLICK);
-        mAlt.assertNotCalled_onSingleTapConfirmed();
-
-        mRouter.onDoubleTap(Mouse.CLICK);
-        mHandler.assertCalled_onDoubleTap(Mouse.CLICK);
-        mAlt.assertNotCalled_onDoubleTap();
-
-        mRouter.onDoubleTapEvent(Mouse.CLICK);
-        mHandler.assertCalled_onDoubleTapEvent(Mouse.CLICK);
-        mAlt.assertNotCalled_onDoubleTapEvent();
-    }
-
-    @Test
-    public void testFallsback() {
-        mRouter = new GestureRouter<>(mAlt);
-        mRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mHandler);
-
-        mRouter.onDown(Touch.TAP);
-        mAlt.assertCalled_onDown(Touch.TAP);
-
-        mRouter.onShowPress(Touch.TAP);
-        mAlt.assertCalled_onShowPress(Touch.TAP);
-
-        mRouter.onSingleTapUp(Touch.TAP);
-        mAlt.assertCalled_onSingleTapUp(Touch.TAP);
-
-        mRouter.onScroll(null, Touch.TAP, -1, -1);
-        mAlt.assertCalled_onScroll(null, Touch.TAP, -1, -1);
-
-        mRouter.onLongPress(Touch.TAP);
-        mAlt.assertCalled_onLongPress(Touch.TAP);
-
-        mRouter.onFling(null, Touch.TAP, -1, -1);
-        mAlt.assertCalled_onFling(null, Touch.TAP, -1, -1);
-
-        mRouter.onSingleTapConfirmed(Touch.TAP);
-        mAlt.assertCalled_onSingleTapConfirmed(Touch.TAP);
-
-        mRouter.onDoubleTap(Touch.TAP);
-        mAlt.assertCalled_onDoubleTap(Touch.TAP);
-
-        mRouter.onDoubleTapEvent(Touch.TAP);
-        mAlt.assertCalled_onDoubleTapEvent(Touch.TAP);
-    }
-
-    @Test
-    public void testEatsEventsWhenNoFallback() {
-        mRouter = new GestureRouter<>();
-        // Register the the delegate on mouse so touch events don't get handled.
-        mRouter.register(MotionEvent.TOOL_TYPE_MOUSE, mHandler);
-
-        mRouter.onDown(Touch.TAP);
-        mAlt.assertNotCalled_onDown();
-
-        mRouter.onShowPress(Touch.TAP);
-        mAlt.assertNotCalled_onShowPress();
-
-        mRouter.onSingleTapUp(Touch.TAP);
-        mAlt.assertNotCalled_onSingleTapUp();
-
-        mRouter.onScroll(null, Touch.TAP, -1, -1);
-        mAlt.assertNotCalled_onScroll();
-
-        mRouter.onLongPress(Touch.TAP);
-        mAlt.assertNotCalled_onLongPress();
-
-        mRouter.onFling(null, Touch.TAP, -1, -1);
-        mAlt.assertNotCalled_onFling();
-
-        mRouter.onSingleTapConfirmed(Touch.TAP);
-        mAlt.assertNotCalled_onSingleTapConfirmed();
-
-        mRouter.onDoubleTap(Touch.TAP);
-        mAlt.assertNotCalled_onDoubleTap();
-
-        mRouter.onDoubleTapEvent(Touch.TAP);
-        mAlt.assertNotCalled_onDoubleTapEvent();
-    }
-
-    private static final class TestHandler implements OnGestureListener, OnDoubleTapListener {
-
-        private final Spy mSpy = Mockito.mock(Spy.class);
-
-        @Override
-        public boolean onDown(MotionEvent e) {
-            return mSpy.onDown(e);
-        }
-
-        @Override
-        public void onShowPress(MotionEvent e) {
-            mSpy.onShowPress(e);
-        }
-
-        @Override
-        public boolean onSingleTapUp(MotionEvent e) {
-            return mSpy.onSingleTapUp(e);
-        }
-
-        @Override
-        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-            return mSpy.onScroll(e1, e2, distanceX, distanceY);
-        }
-
-        @Override
-        public void onLongPress(MotionEvent e) {
-            mSpy.onLongPress(e);
-        }
-
-        @Override
-        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-            return mSpy.onFling(e1, e2, velocityX, velocityY);
-        }
-
-        @Override
-        public boolean onSingleTapConfirmed(MotionEvent e) {
-            return mSpy.onSingleTapConfirmed(e);
-        }
-
-        @Override
-        public boolean onDoubleTap(MotionEvent e) {
-            return mSpy.onDoubleTap(e);
-        }
-
-        @Override
-        public boolean onDoubleTapEvent(MotionEvent e) {
-            return mSpy.onDoubleTapEvent(e);
-        }
-
-        void assertCalled_onDown(MotionEvent e) {
-            verify(mSpy).onDown(e);
-        }
-
-        void assertCalled_onShowPress(MotionEvent e) {
-            verify(mSpy).onShowPress(e);
-        }
-
-        void assertCalled_onSingleTapUp(MotionEvent e) {
-            verify(mSpy).onSingleTapUp(e);
-        }
-
-        void assertCalled_onScroll(MotionEvent e1, MotionEvent e2, float x, float y) {
-            verify(mSpy).onScroll(e1, e2, x, y);
-        }
-
-        void assertCalled_onLongPress(MotionEvent e) {
-            verify(mSpy).onLongPress(e);
-        }
-
-        void assertCalled_onFling(MotionEvent e1, MotionEvent e2, float x, float y) {
-            Mockito.verify(mSpy).onFling(e1, e2, x, y);
-        }
-
-        void assertCalled_onSingleTapConfirmed(MotionEvent e) {
-            Mockito.verify(mSpy).onSingleTapConfirmed(e);
-        }
-
-        void assertCalled_onDoubleTap(MotionEvent e) {
-            Mockito.verify(mSpy).onDoubleTap(e);
-        }
-
-        void assertCalled_onDoubleTapEvent(MotionEvent e) {
-            Mockito.verify(mSpy).onDoubleTapEvent(e);
-        }
-
-        void assertNotCalled_onDown() {
-            verify(mSpy, never()).onDown(any());
-        }
-
-        void assertNotCalled_onShowPress() {
-            verify(mSpy, never()).onShowPress(any());
-        }
-
-        void assertNotCalled_onSingleTapUp() {
-            verify(mSpy, never()).onSingleTapUp(any());
-        }
-
-        void assertNotCalled_onScroll() {
-            verify(mSpy, never()).onScroll(any(), any(), anyFloat(), anyFloat());
-        }
-
-        void assertNotCalled_onLongPress() {
-            verify(mSpy, never()).onLongPress(any());
-        }
-
-        void assertNotCalled_onFling() {
-            Mockito.verify(mSpy, never()).onFling(any(), any(), anyFloat(), anyFloat());
-        }
-
-        void assertNotCalled_onSingleTapConfirmed() {
-            Mockito.verify(mSpy, never()).onSingleTapConfirmed(any());
-        }
-
-        void assertNotCalled_onDoubleTap() {
-            Mockito.verify(mSpy, never()).onDoubleTap(any());
-        }
-
-        void assertNotCalled_onDoubleTapEvent() {
-            Mockito.verify(mSpy, never()).onDoubleTapEvent(any());
-        }
-    }
-
-    private static interface Spy extends OnGestureListener, OnDoubleTapListener {}
-}
diff --git a/tests/unit/com/android/documentsui/selection/GestureSelectionHelperTest.java b/tests/unit/com/android/documentsui/selection/GestureSelectionHelperTest.java
deleted file mode 100644
index df69fdf..0000000
--- a/tests/unit/com/android/documentsui/selection/GestureSelectionHelperTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView;
-
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestData;
-import com.android.documentsui.testing.SelectionHelpers;
-import com.android.documentsui.testing.TestEvents;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class GestureSelectionHelperTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-    private static final MotionEvent DOWN = TestEvents.builder()
-            .action(MotionEvent.ACTION_DOWN)
-            .location(1, 1)
-            .build();
-
-    private static final MotionEvent MOVE = TestEvents.builder()
-            .action(MotionEvent.ACTION_MOVE)
-            .location(1, 1)
-            .build();
-
-    private static final MotionEvent UP = TestEvents.builder()
-            .action(MotionEvent.ACTION_UP)
-            .location(1, 1)
-            .build();
-
-    private GestureSelectionHelper mHelper;
-    private SelectionHelper mSelectionHelper;
-    private SelectionProbe mSelection;
-    private ContentLock mLock;
-    private TestItemDetailsLookup mItemLookup;
-    private TestViewDelegate mView;
-
-    @Before
-    public void setUp() {
-        mSelectionHelper = SelectionHelpers.createTestInstance(ITEMS);
-        mSelection = new SelectionProbe(mSelectionHelper);
-        mLock = new ContentLock();
-        mItemLookup = new TestItemDetailsLookup();
-        mItemLookup.initAt(3);
-        mView = new TestViewDelegate();
-        mHelper = new GestureSelectionHelper(mSelectionHelper, mView, mLock, mItemLookup);
-    }
-
-    @Test
-    public void testIgnoresDown_NoPosition() {
-        mView.mNextPosition = RecyclerView.NO_POSITION;
-        assertFalse(mHelper.onInterceptTouchEvent(null, DOWN));
-    }
-
-    @Test
-    public void testIgnoresDown_NoItemDetails() {
-        mItemLookup.reset();
-        assertFalse(mHelper.onInterceptTouchEvent(null, DOWN));
-    }
-
-    @Test
-    public void testNoStartOnIllegalPosition() {
-        mView.mNextPosition = -1;
-        mHelper.onInterceptTouchEvent(null, DOWN);
-        mHelper.start();
-        assertFalse(mLock.isLocked());
-    }
-
-    @Test
-    public void testDoesNotClaimDownOnItem() {
-        mView.mNextPosition = 0;
-        assertFalse(mHelper.onInterceptTouchEvent(null, DOWN));
-    }
-
-    @Test
-    public void testClaimsMoveIfStarted() {
-        mView.mNextPosition = 0;
-        // TODO(b/109808552): This should be removed with that bug is fixed because it will be a
-        // no-op at that time.
-        mHelper.onInterceptTouchEvent(null, DOWN);
-
-        // Normally, this is controller by the TouchSelectionHelper via a a long press gesture.
-        mSelectionHelper.select("1");
-        mSelectionHelper.anchorRange(1);
-        mHelper.start();
-        assertTrue(mHelper.onInterceptTouchEvent(null, MOVE));
-    }
-
-    @Test
-    public void testCreatesRangeSelection() {
-        mView.mNextPosition = 1;
-        mHelper.onInterceptTouchEvent(null, DOWN);
-        // Another way we are implicitly coupled to TouchInputHandler, is that we depend on
-        // long press to establish the initial anchor point. Without that we'll get an
-        // error when we try to extend the range.
-
-        mSelectionHelper.select("1");
-        mSelectionHelper.anchorRange(1);
-        mHelper.start();
-
-        mHelper.onTouchEvent(null, MOVE);
-
-        mView.mNextPosition = 9;
-        mHelper.onTouchEvent(null, MOVE);
-        mHelper.onTouchEvent(null, UP);
-
-        mSelection.assertRangeSelected(1, 9);
-    }
-
-    private static final class TestViewDelegate extends GestureSelectionHelper.ViewDelegate {
-
-        private int mNextPosition = RecyclerView.NO_POSITION;
-
-        @Override
-        int getHeight() {
-            return 1000;
-        }
-
-        @Override
-        int getItemUnder(MotionEvent e) {
-            return mNextPosition;
-        }
-
-        @Override
-        int getLastGlidedItemPosition(MotionEvent e) {
-            return mNextPosition;
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/GestureSelectionHelper_RecyclerViewDelegateTest.java b/tests/unit/com/android/documentsui/selection/GestureSelectionHelper_RecyclerViewDelegateTest.java
deleted file mode 100644
index 9e05d0c..0000000
--- a/tests/unit/com/android/documentsui/selection/GestureSelectionHelper_RecyclerViewDelegateTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.documentsui.selection.GestureSelectionHelper.RecyclerViewDelegate;
-import com.android.documentsui.testing.TestEvents;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class GestureSelectionHelper_RecyclerViewDelegateTest {
-
-    // Simulate a (20, 20) box locating at (20, 20)
-    static final int LEFT_BORDER = 20;
-    static final int RIGHT_BORDER = 40;
-    static final int TOP_BORDER = 20;
-    static final int BOTTOM_BORDER = 40;
-
-    @Test
-    public void testLtrPastLastItem() {
-        MotionEvent event = createEvent(100, 100);
-        assertTrue(RecyclerViewDelegate.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_LTR));
-    }
-
-    @Test
-    public void testLtrPastLastItem_Inverse() {
-        MotionEvent event = createEvent(10, 10);
-        assertFalse(RecyclerViewDelegate.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_LTR));
-    }
-
-    @Test
-    public void testRtlPastLastItem() {
-        MotionEvent event = createEvent(10, 30);
-        assertTrue(RecyclerViewDelegate.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_RTL));
-    }
-
-    @Test
-    public void testRtlPastLastItem_Inverse() {
-        MotionEvent event = createEvent(100, 100);
-        assertFalse(RecyclerViewDelegate.isPastLastItem(
-                TOP_BORDER, LEFT_BORDER, RIGHT_BORDER, event, View.LAYOUT_DIRECTION_RTL));
-    }
-
-    private static MotionEvent createEvent(int x, int y) {
-        return TestEvents.builder().action(MotionEvent.ACTION_MOVE).location(x, y).build();
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/GridModelTest.java b/tests/unit/com/android/documentsui/selection/GridModelTest.java
deleted file mode 100644
index 1cb2900..0000000
--- a/tests/unit/com/android/documentsui/selection/GridModelTest.java
+++ /dev/null
@@ -1,493 +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.documentsui.selection;
-
-import static com.android.documentsui.selection.GridModel.NOT_SET;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView.OnScrollListener;
-
-import com.android.documentsui.selection.BandSelectionHelper.BandHost;
-import com.android.documentsui.selection.testing.SelectionPredicates;
-import com.android.documentsui.selection.testing.TestAdapter;
-import com.android.documentsui.selection.testing.TestStableIdProvider;
-
-import org.junit.After;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class GridModelTest {
-
-    private static final int VIEW_PADDING_PX = 5;
-    private static final int CHILD_VIEW_EDGE_PX = 100;
-    private static final int VIEWPORT_HEIGHT = 500;
-
-    private GridModel mModel;
-    private TestHost mHost;
-    private TestAdapter mAdapter;
-    private Set<String> mLastSelection;
-    private int mViewWidth;
-
-    // TLDR: Don't call model.{start|resize}Selection; use the local #startSelection and
-    // #resizeSelection methods instead.
-    //
-    // The reason for this is that selection is stateful and involves operations that take the
-    // current UI state (e.g scrolling) into account. This test maintains its own copy of the
-    // selection bounds as control data for verifying selections. Keep this data in sync by calling
-    // #startSelection and
-    // #resizeSelection.
-    private Point mSelectionOrigin;
-    private Point mSelectionPoint;
-
-    @After
-    public void tearDown() {
-        mModel = null;
-        mHost = null;
-        mLastSelection = null;
-    }
-
-    @Test
-    public void testSelectionLeftOfItems() {
-        initData(20, 5);
-        startSelection(new Point(0, 10));
-        resizeSelection(new Point(1, 11));
-        assertNoSelection();
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testSelectionRightOfItems() {
-        initData(20, 4);
-        startSelection(new Point(mViewWidth - 1, 10));
-        resizeSelection(new Point(mViewWidth - 2, 11));
-        assertNoSelection();
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testSelectionAboveItems() {
-        initData(20, 4);
-        startSelection(new Point(10, 0));
-        resizeSelection(new Point(11, 1));
-        assertNoSelection();
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testSelectionBelowItems() {
-        initData(5, 4);
-        startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
-        resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
-        assertNoSelection();
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testVerticalSelectionBetweenItems() {
-        initData(20, 4);
-        startSelection(new Point(106, 0));
-        resizeSelection(new Point(107, 200));
-        assertNoSelection();
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testHorizontalSelectionBetweenItems() {
-        initData(20, 4);
-        startSelection(new Point(0, 105));
-        resizeSelection(new Point(200, 106));
-        assertNoSelection();
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testGrowingAndShrinkingSelection() {
-        initData(20, 4);
-        startSelection(new Point(0, 0));
-
-        resizeSelection(new Point(5, 5));
-        verifySelection();
-
-        resizeSelection(new Point(109, 109));
-        verifySelection();
-
-        resizeSelection(new Point(110, 109));
-        verifySelection();
-
-        resizeSelection(new Point(110, 110));
-        verifySelection();
-
-        resizeSelection(new Point(214, 214));
-        verifySelection();
-
-        resizeSelection(new Point(215, 214));
-        verifySelection();
-
-        resizeSelection(new Point(214, 214));
-        verifySelection();
-
-        resizeSelection(new Point(110, 110));
-        verifySelection();
-
-        resizeSelection(new Point(110, 109));
-        verifySelection();
-
-        resizeSelection(new Point(109, 109));
-        verifySelection();
-
-        resizeSelection(new Point(5, 5));
-        verifySelection();
-
-        resizeSelection(new Point(0, 0));
-        verifySelection();
-
-        assertEquals(NOT_SET, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testSelectionMovingAroundOrigin() {
-        initData(16, 4);
-
-        startSelection(new Point(210, 210));
-        resizeSelection(new Point(mViewWidth - 1, 0));
-        verifySelection();
-
-        resizeSelection(new Point(0, 0));
-        verifySelection();
-
-        resizeSelection(new Point(0, 420));
-        verifySelection();
-
-        resizeSelection(new Point(mViewWidth - 1, 420));
-        verifySelection();
-
-        // This is manually figured and will need to be adjusted if the separator position is
-        // changed.
-        assertEquals(7, mModel.getPositionNearestOrigin());
-    }
-
-    @Test
-    public void testScrollingBandSelect() {
-        initData(40, 4);
-
-        startSelection(new Point(0, 0));
-        resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
-        verifySelection();
-
-        scroll(CHILD_VIEW_EDGE_PX);
-        verifySelection();
-
-        resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
-        verifySelection();
-
-        scroll(CHILD_VIEW_EDGE_PX);
-        verifySelection();
-
-        scroll(-2 * CHILD_VIEW_EDGE_PX);
-        verifySelection();
-
-        resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
-        verifySelection();
-
-        assertEquals(0, mModel.getPositionNearestOrigin());
-    }
-
-    private void initData(final int numChildren, int numColumns) {
-        mHost = new TestHost(numChildren, numColumns);
-        mAdapter = new TestAdapter() {
-            @Override
-            public String getStableId(int position) {
-                return Integer.toString(position);
-            }
-
-            @Override
-            public int getItemCount() {
-                return numChildren;
-            }
-        };
-
-        mViewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
-
-        mModel = new GridModel(
-                mHost,
-                new TestStableIdProvider(mAdapter),
-                SelectionPredicates.CAN_SET_ANYTHING);
-
-        mModel.addOnSelectionChangedListener(
-                new GridModel.SelectionObserver() {
-                    @Override
-                    public void onSelectionChanged(Set<String> updatedSelection) {
-                        mLastSelection = updatedSelection;
-                    }
-                });
-    }
-
-    /** Returns the current selection area as a Rect. */
-    private Rect getSelectionArea() {
-        // Construct a rect from the two selection points.
-        Rect selectionArea = new Rect(
-                mSelectionOrigin.x, mSelectionOrigin.y, mSelectionOrigin.x, mSelectionOrigin.y);
-        selectionArea.union(mSelectionPoint.x, mSelectionPoint.y);
-        // Rect intersection tests are exclusive of bounds, while the MSM's selection code is
-        // inclusive. Expand the rect by 1 pixel in all directions to account for this.
-        selectionArea.inset(-1, -1);
-
-        return selectionArea;
-    }
-
-    /** Asserts that the selection is currently empty. */
-    private void assertNoSelection() {
-        assertEquals("Unexpected items " + mLastSelection + " in selection " + getSelectionArea(),
-                0, mLastSelection.size());
-    }
-
-    /** Verifies the selection using actual bbox checks. */
-    private void verifySelection() {
-        Rect selectionArea = getSelectionArea();
-        for (TestHost.Item item: mHost.items) {
-            if (Rect.intersects(selectionArea, item.rect)) {
-                assertTrue("Expected item " + item + " was not in selection " + selectionArea,
-                        mLastSelection.contains(item.name));
-            } else {
-                assertFalse("Unexpected item " + item + " in selection" + selectionArea,
-                        mLastSelection.contains(item.name));
-            }
-        }
-    }
-
-    private void startSelection(Point p) {
-        mModel.startCapturing(p);
-        mSelectionOrigin = mHost.createAbsolutePoint(p);
-    }
-
-    private void resizeSelection(Point p) {
-        mModel.resizeSelection(p);
-        mSelectionPoint = mHost.createAbsolutePoint(p);
-    }
-
-    private void scroll(int dy) {
-        assertTrue(mHost.verticalOffset + VIEWPORT_HEIGHT + dy <= mHost.getTotalHeight());
-        mHost.verticalOffset += dy;
-        // Correct the cached selection point as well.
-        mSelectionPoint.y += dy;
-        mHost.mScrollListener.onScrolled(null, 0, dy);
-    }
-
-    private static final class TestHost extends BandHost {
-
-        private final int mNumColumns;
-        private final int mNumRows;
-        private final int mNumChildren;
-        private final int mSeparatorPosition;
-
-        public int horizontalOffset = 0;
-        public int verticalOffset = 0;
-        private List<Item> items = new ArrayList<>();
-
-        // Installed by GridModel on construction.
-        private @Nullable OnScrollListener mScrollListener;
-
-        public TestHost(int numChildren, int numColumns) {
-            mNumChildren = numChildren;
-            mNumColumns = numColumns;
-            mSeparatorPosition = mNumColumns + 1;
-            mNumRows = setupGrid();
-        }
-
-        private int setupGrid() {
-            // Split the input set into folders and documents. Do this such that there is a
-            // partially-populated row in the middle of the grid, to test corner cases in layout
-            // code.
-            int y = VIEW_PADDING_PX;
-            int i = 0;
-            int numRows = 0;
-            while (i < mNumChildren) {
-                int top = y;
-                int height = CHILD_VIEW_EDGE_PX;
-                int width = CHILD_VIEW_EDGE_PX;
-                for (int j = 0; j < mNumColumns && i < mNumChildren; j++) {
-                    int left = VIEW_PADDING_PX + (j * (width + VIEW_PADDING_PX));
-                    items.add(new Item(
-                            Integer.toString(i),
-                            new Rect(
-                                    left,
-                                    top,
-                                    left + width - 1,
-                                    top + height - 1)));
-
-                    // Create a partially populated row at the separator position.
-                    if (++i == mSeparatorPosition) {
-                        break;
-                    }
-                }
-                y += height + VIEW_PADDING_PX;
-                numRows++;
-            }
-
-            return numRows;
-        }
-
-        private int getTotalHeight() {
-            return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
-        }
-
-        private int getFirstVisibleRowIndex() {
-            return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
-        }
-
-        private int getLastVisibleRowIndex() {
-            int lastVisibleRowUncapped =
-                    (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
-            return Math.min(lastVisibleRowUncapped, mNumRows - 1);
-        }
-
-        private int getNumItemsInRow(int index) {
-            assertTrue(index >= 0 && index < mNumRows);
-            int mod = mSeparatorPosition % mNumColumns;
-            if (index == (mSeparatorPosition / mNumColumns)) {
-                // The row containing the separator may be incomplete
-                return mod > 0 ? mod : mNumColumns;
-            }
-            // Account for the partial separator row in the final row tally.
-            if (index == mNumRows - 1) {
-                // The last row may be incomplete
-                int finalRowCount = (mNumChildren - mod) % mNumColumns;
-                return finalRowCount > 0 ? finalRowCount : mNumColumns;
-            }
-
-            return mNumColumns;
-        }
-
-        @Override
-        public void addOnScrollListener(OnScrollListener listener) {
-            mScrollListener = listener;
-        }
-
-        @Override
-        public void removeOnScrollListener(OnScrollListener listener) {}
-
-        @Override
-        public Point createAbsolutePoint(Point relativePoint) {
-            return new Point(
-                    relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
-        }
-
-        @Override
-        public int getVisibleChildCount() {
-            int childCount = 0;
-            for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
-                childCount += getNumItemsInRow(i);
-            }
-            return childCount;
-        }
-
-        @Override
-        public int getAdapterPositionAt(int index) {
-            // Account for partial rows by actually tallying up the items in hidden rows.
-            int hiddenCount = 0;
-            for (int i = 0; i < getFirstVisibleRowIndex(); i++) {
-                hiddenCount += getNumItemsInRow(i);
-            }
-            return index + hiddenCount;
-        }
-
-        @Override
-        public Rect getAbsoluteRectForChildViewAt(int index) {
-            int adapterPosition = getAdapterPositionAt(index);
-            return items.get(adapterPosition).rect;
-        }
-
-        @Override
-        public int getChildCount() {
-            return mNumChildren;
-        }
-
-        @Override
-        public int getColumnCount() {
-            return mNumColumns;
-        }
-
-        @Override
-        public void showBand(Rect rect) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void hideBand() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void scrollBy(int dy) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getHeight() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void invalidateView() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void runAtNextFrame(Runnable r) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void removeCallback(Runnable r) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean hasView(int adapterPosition) {
-            return true;
-        }
-
-        public static final class Item {
-            public String name;
-            public Rect rect;
-
-            public Item(String n, Rect r) {
-                name = n;
-                rect = r;
-            }
-
-            @Override
-            public String toString() {
-                return name + ": " + rect;
-            }
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/MouseInputHandlerTest.java b/tests/unit/com/android/documentsui/selection/MouseInputHandlerTest.java
deleted file mode 100644
index f1bf556..0000000
--- a/tests/unit/com/android/documentsui/selection/MouseInputHandlerTest.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static com.android.documentsui.testing.TestEvents.Mouse.ALT_CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.CTRL_CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.SECONDARY_CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.SHIFT_CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.TERTIARY_CLICK;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.testing.SelectionHelpers;
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestData;
-import com.android.documentsui.selection.testing.TestEvents;
-import com.android.documentsui.selection.testing.TestMouseCallbacks;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class MouseInputHandlerTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private MouseInputHandler mInputDelegate;
-    private TestMouseCallbacks mCallbacks;
-    private TestItemDetailsLookup mDetailsLookup;
-    private SelectionProbe mSelection;
-    private SelectionHelper mSelectionMgr;
-
-    private TestEvents.Builder mEvent;
-
-    @Before
-    public void setUp() {
-
-        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
-        mDetailsLookup = new TestItemDetailsLookup();
-        mSelection = new SelectionProbe(mSelectionMgr);
-
-        mCallbacks = new TestMouseCallbacks();
-        mInputDelegate = new MouseInputHandler(mSelectionMgr, mDetailsLookup, mCallbacks);
-
-        mEvent = TestEvents.builder().mouse();
-        mDetailsLookup.initAt(RecyclerView.NO_POSITION);
-    }
-
-    @Test
-    public void testConfirmedClick_StartsSelection() {
-        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mSelection.assertSelection(11);
-    }
-
-    @Test
-    public void testClickOnSelectRegion_AddsToSelection() {
-        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(10).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapUp(CLICK);
-
-        mSelection.assertSelected(10, 11);
-    }
-
-    @Test
-    public void testClickOnIconOfSelectedItem_RemovesFromSelection() {
-        mDetailsLookup.initAt(8).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-        mSelection.assertSelected(8, 9, 10, 11);
-
-        mDetailsLookup.initAt(9);
-        mInputDelegate.onSingleTapUp(CLICK);
-        mSelection.assertSelected(8, 10, 11);
-    }
-
-    @Test
-    public void testRightClickDown_StartsContextMenu() {
-        mInputDelegate.onDown(SECONDARY_CLICK);
-
-        mCallbacks.assertLastEvent(SECONDARY_CLICK);
-    }
-
-    @Test
-    public void testAltClickDown_StartsContextMenu() {
-        mInputDelegate.onDown(ALT_CLICK);
-
-        mCallbacks.assertLastEvent(ALT_CLICK);
-    }
-
-    @Test
-    public void testScroll_shouldTrap() {
-        mDetailsLookup.initAt(0);
-        assertTrue(mInputDelegate.onScroll(
-                null,
-                mEvent.action(MotionEvent.ACTION_MOVE).primary().build(),
-                -1,
-                -1));
-    }
-
-    @Test
-    public void testScroll_NoTrapForTwoFinger() {
-        mDetailsLookup.initAt(0);
-        assertFalse(mInputDelegate.onScroll(
-                null,
-                mEvent.action(MotionEvent.ACTION_MOVE).build(),
-                -1,
-                -1));
-    }
-
-    @Test
-    public void testUnconfirmedCtrlClick_AddsToExistingSelection() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(CTRL_CLICK);
-
-        mSelection.assertSelection(7, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftClick_ExtendsSelection() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-    }
-
-    @Test
-    public void testConfirmedShiftClick_ExtendsSelectionFromOriginFocus() {
-        TestItemDetails item = mDetailsLookup.initAt(7);
-        mCallbacks.focusItem(item);
-
-        // This is a hack-y test, since the real FocusManager would've set range begin itself.
-        mSelectionMgr.anchorRange(7);
-        mSelection.assertNoSelection();
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapConfirmed(SHIFT_CLICK);
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftClick_RotatesAroundOrigin() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-
-        mDetailsLookup.initAt(5);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertSelection(5, 6, 7);
-        mSelection.assertNotSelected(8, 9, 10, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftCtrlClick_Combination() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-
-        mDetailsLookup.initAt(5);
-        mInputDelegate.onSingleTapUp(CTRL_CLICK);
-
-        mSelection.assertSelection(5, 7, 8, 9, 10, 11);
-    }
-
-    @Test
-    public void testUnconfirmedShiftCtrlClick_ShiftTakesPriority() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(mEvent.ctrl().shift().build());
-
-        mSelection.assertSelection(7, 8, 9, 10, 11);
-    }
-
-    // TODO: Add testSpaceBar_Previews, but we need to set a system property
-    // to have a deterministic state.
-
-    @Test
-    public void testDoubleClick_Opens() {
-        TestItemDetails doc = mDetailsLookup.initAt(11);
-        mInputDelegate.onDoubleTap(CLICK);
-
-        mCallbacks.assertActivated(doc);
-    }
-
-    @Test
-    public void testMiddleClick_DoesNothing() {
-        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(TERTIARY_CLICK);
-
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testClickOff_ClearsSelection() {
-        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(RecyclerView.NO_POSITION);
-        mInputDelegate.onSingleTapUp(CLICK);
-
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testClick_Focuses() {
-        mDetailsLookup.initAt(11).setInItemSelectRegion(false);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mCallbacks.assertHasFocus(true);
-        mCallbacks.assertFocused("11");
-    }
-
-    @Test
-    public void testClickOff_ClearsFocus() {
-        mDetailsLookup.initAt(11).setInItemSelectRegion(false);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-        mCallbacks.assertHasFocus(true);
-
-        mDetailsLookup.initAt(RecyclerView.NO_POSITION);
-        mInputDelegate.onSingleTapUp(CLICK);
-        mCallbacks.assertHasFocus(false);
-    }
-
-    @Test
-    public void testClickOffSelection_RemovesSelectionAndFocuses() {
-        mDetailsLookup.initAt(1).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(5);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertSelection(1, 2, 3, 4, 5);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(CLICK);
-
-        mCallbacks.assertFocused("11");
-        mSelection.assertNoSelection();
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/MouseInputHandler_RangeTest.java b/tests/unit/com/android/documentsui/selection/MouseInputHandler_RangeTest.java
deleted file mode 100644
index 939e778..0000000
--- a/tests/unit/com/android/documentsui/selection/MouseInputHandler_RangeTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static com.android.documentsui.testing.TestEvents.Mouse.CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.SECONDARY_CLICK;
-import static com.android.documentsui.testing.TestEvents.Mouse.SHIFT_CLICK;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.testing.SelectionHelpers;
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestData;
-import com.android.documentsui.selection.testing.TestMouseCallbacks;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * MouseInputDelegate / SelectHelper integration test covering the shared
- * responsibility of range selection.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class MouseInputHandler_RangeTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private MouseInputHandler mInputDelegate;
-    private SelectionHelper mSelectionMgr;
-    private SelectionProbe mSelection;
-    private TestMouseCallbacks mCallbacks;
-    private TestItemDetailsLookup mDetailsLookup;
-
-    @Before
-    public void setUp() {
-        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
-        mDetailsLookup = new TestItemDetailsLookup();
-        mSelection = new SelectionProbe(mSelectionMgr);
-
-        mCallbacks = new TestMouseCallbacks();
-        mInputDelegate = new MouseInputHandler(mSelectionMgr, mDetailsLookup, mCallbacks);
-    }
-
-    @Test
-    public void testExtendRange() {
-        // uni-click just focuses.
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(7, 11);
-    }
-
-    @Test
-    public void testExtendRangeContinues() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mDetailsLookup.initAt(21);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(7, 21);
-    }
-
-    @Test
-    public void testMultipleContiguousRanges() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        // click without shift sets a new range start point.
-        TestItemDetails item = mDetailsLookup.initAt(20);
-        mInputDelegate.onSingleTapUp(CLICK);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mCallbacks.focusItem(item);
-
-        mDetailsLookup.initAt(25);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-        mInputDelegate.onSingleTapConfirmed(SHIFT_CLICK);
-
-        mSelection.assertRangeNotSelected(7, 11);
-        mSelection.assertRangeSelected(20, 25);
-        mSelection.assertSelectionSize(6);
-    }
-
-    @Test
-    public void testReducesSelectionRange() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(17);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mDetailsLookup.initAt(10);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(7, 10);
-    }
-
-    @Test
-    public void testReducesSelectionRange_Reverse() {
-        mDetailsLookup.initAt(17).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(7);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mDetailsLookup.initAt(14);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(14, 17);
-    }
-
-    @Test
-    public void testExtendsRange_Reverse() {
-        mDetailsLookup.initAt(12).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(5);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(5, 12);
-    }
-
-    @Test
-    public void testExtendsRange_ReversesAfterForwardClick() {
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapConfirmed(CLICK);
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mDetailsLookup.initAt(0);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(0, 7);
-    }
-
-    @Test
-    public void testRightClickEstablishesRange() {
-
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onDown(SECONDARY_CLICK);
-        // This next method call simulates the behavior of the system event dispatch code.
-        // UserInputHandler depends on a specific sequence of events for internal
-        // state to remain valid. It's not an awesome arrangement, but it is currently
-        // necessary.
-        //
-        // See: UserInputHandler.MouseDelegate#mHandledOnDown;
-        mInputDelegate.onSingleTapUp(SECONDARY_CLICK);
-
-        mDetailsLookup.initAt(11);
-        // Now we can send a subsequent event that should extend selection.
-        mInputDelegate.onDown(SHIFT_CLICK);
-        mInputDelegate.onSingleTapUp(SHIFT_CLICK);
-
-        mSelection.assertRangeSelection(7, 11);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/SelectionTest.java b/tests/unit/com/android/documentsui/selection/SelectionTest.java
deleted file mode 100644
index fcf525b..0000000
--- a/tests/unit/com/android/documentsui/selection/SelectionTest.java
+++ /dev/null
@@ -1,200 +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.documentsui.selection;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.google.common.collect.Sets;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SelectionTest {
-
-    private Selection selection;
-
-    private String[] ids = new String[]{
-            "foo",
-            "43",
-            "auth|id=@53di*/f3#d"
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        selection = new Selection();
-        selection.add(ids[0]);
-        selection.add(ids[1]);
-        selection.add(ids[2]);
-    }
-
-    @Test
-    public void testAdd() {
-        // We added in setUp.
-        assertEquals(3, selection.size());
-        assertContains(ids[0]);
-        assertContains(ids[1]);
-        assertContains(ids[2]);
-    }
-
-    @Test
-    public void testRemove() {
-        selection.remove(ids[0]);
-        selection.remove(ids[2]);
-        assertEquals(1, selection.size());
-        assertContains(ids[1]);
-    }
-
-    @Test
-    public void testClear() {
-        selection.clear();
-        assertEquals(0, selection.size());
-    }
-
-    @Test
-    public void testIsEmpty() {
-        assertTrue(new Selection().isEmpty());
-        selection.clear();
-        assertTrue(selection.isEmpty());
-    }
-
-    @Test
-    public void testSize() {
-        Selection other = new Selection();
-        for (int i = 0; i < selection.size(); i++) {
-            other.add(ids[i]);
-        }
-        assertEquals(selection.size(), other.size());
-    }
-
-    @Test
-    public void testEqualsSelf() {
-        assertEquals(selection, selection);
-    }
-
-    @Test
-    public void testEqualsOther() {
-        Selection other = new Selection();
-        other.add(ids[0]);
-        other.add(ids[1]);
-        other.add(ids[2]);
-        assertEquals(selection, other);
-        assertEquals(selection.hashCode(), other.hashCode());
-    }
-
-    @Test
-    public void testEqualsCopy() {
-        Selection other = new Selection();
-        other.copyFrom(selection);
-        assertEquals(selection, other);
-        assertEquals(selection.hashCode(), other.hashCode());
-    }
-
-    @Test
-    public void testNotEquals() {
-        Selection other = new Selection();
-        other.add("foobar");
-        assertFalse(selection.equals(other));
-    }
-
-    @Test
-    public void testIntersection_empty0() {
-        Selection testSelection = new Selection();
-        testSelection.intersect(new HashSet<String>());
-        assertTrue(testSelection.isEmpty());
-    }
-
-    @Test
-    public void testIntersection_empty1() {
-        Selection testSelection = new Selection();
-        testSelection.intersect(Sets.newHashSet("foo"));
-        assertTrue(testSelection.isEmpty());
-    }
-
-    @Test
-    public void testIntersection_empty2() {
-        assertFalse(selection.isEmpty());
-        selection.intersect(new HashSet<String>());
-        assertTrue(selection.isEmpty());
-    }
-
-    @Test
-    public void testIntersection_exclusive() {
-        String[] ids0 = new String[]{"foo", "bar", "baz"};
-        String[] ids1 = new String[]{"0", "1", "2"};
-
-        Selection testSelection = new Selection();
-        testSelection.add(ids0[0]);
-        testSelection.add(ids0[1]);
-        testSelection.add(ids0[2]);
-
-        Set<String> set = Sets.newHashSet(ids1);
-        testSelection.intersect(set);
-
-        assertTrue(testSelection.isEmpty());
-    }
-
-    @Test
-    public void testIntersection_subset() {
-        String[] ids0 = new String[]{"foo", "bar", "baz"};
-        String[] ids1 = new String[]{"0", "baz", "1", "foo", "2"};
-
-        Selection testSelection = new Selection();
-        testSelection.add(ids0[0]);
-        testSelection.add(ids0[1]);
-        testSelection.add(ids0[2]);
-
-        testSelection.intersect(Sets.newHashSet(ids1));
-
-        assertTrue(testSelection.contains("foo"));
-        assertFalse(testSelection.contains("bar"));
-        assertTrue(testSelection.contains("baz"));
-    }
-
-    @Test
-    public void testIntersection_all() {
-        String[] ids0 = new String[]{"foo", "bar", "baz"};
-        String[] ids1 = new String[]{"0", "baz", "1", "foo", "2", "bar"};
-
-        Selection testSelection = new Selection();
-        testSelection.add(ids0[0]);
-        testSelection.add(ids0[1]);
-        testSelection.add(ids0[2]);
-
-        Selection control = new Selection();
-        control.copyFrom(testSelection);
-
-        testSelection.intersect(Sets.newHashSet(ids1));
-
-        assertTrue(testSelection.equals(control));
-    }
-
-    private void assertContains(String id) {
-        String err = String.format("Selection %s does not contain %s", selection, id);
-        assertTrue(err, selection.contains(id));
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/TestItemDetailsLookup.java b/tests/unit/com/android/documentsui/selection/TestItemDetailsLookup.java
deleted file mode 100644
index a5397a3..0000000
--- a/tests/unit/com/android/documentsui/selection/TestItemDetailsLookup.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection;
-
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import javax.annotation.Nullable;
-
-/**
- * Test impl of ItemDetailsLookup.
- */
-public class TestItemDetailsLookup extends ItemDetailsLookup {
-
-    private @Nullable TestItemDetails mDoc;
-
-    @Override
-    public boolean overItem(MotionEvent e) {
-        return getItemPosition(e) != RecyclerView.NO_POSITION;
-    }
-
-    @Override
-    public boolean overStableItem(MotionEvent e) {
-        return mDoc.getStableId() != null;
-    }
-
-    @Override
-    public boolean inItemDragRegion(MotionEvent e) {
-        return mDoc.inDragRegion(e);
-    }
-
-    @Override
-    public int getItemPosition(MotionEvent e) {
-        return mDoc.getPosition();
-    }
-
-    @Override
-    public boolean inItemSelectRegion(MotionEvent e) {
-        return mDoc.inSelectionHotspot(e);
-    }
-
-    @Override
-    public @Nullable ItemDetails getItemDetails(MotionEvent e) {
-        return mDoc;
-    }
-
-    /**
-     * Creates/installs/returns a new test document. Subsequent calls to
-     * any EventDocLookup methods will consult the newly created doc.
-     */
-    public TestItemDetails initAt(int position) {
-        TestItemDetails doc = new TestItemDetails();
-        doc.at(position);
-        mDoc = doc;
-        return doc;
-    }
-
-    public void reset() {
-        mDoc = null;
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/TouchInputHandlerTest.java b/tests/unit/com/android/documentsui/selection/TouchInputHandlerTest.java
deleted file mode 100644
index c39bfee..0000000
--- a/tests/unit/com/android/documentsui/selection/TouchInputHandlerTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection;
-
-import static com.android.documentsui.testing.TestEvents.Touch.TAP;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.annotation.Nullable;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-import com.android.documentsui.selection.TouchInputHandler.Callbacks;
-import com.android.documentsui.selection.testing.SelectionHelpers;
-import com.android.documentsui.selection.testing.SelectionProbe;
-import com.android.documentsui.selection.testing.TestData;
-import com.android.documentsui.selection.testing.TestSelectionPredicate;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public final class TouchInputHandlerTest {
-
-    private static final List<String> ITEMS = TestData.create(100);
-
-    private TouchInputHandler mInputDelegate;
-    private SelectionHelper mSelectionMgr;
-    private TestSelectionPredicate mSelectionPredicate;
-    private TestRunnable mGestureStarted;
-    private TestCallbacks mCallbacks;
-    private TestItemDetailsLookup mDetailsLookup;
-    private SelectionProbe mSelection;
-
-    @Before
-    public void setUp() {
-        mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS);
-        mDetailsLookup = new TestItemDetailsLookup();
-        mSelectionPredicate = new TestSelectionPredicate();
-        mSelection = new SelectionProbe(mSelectionMgr);
-        mGestureStarted = new TestRunnable();
-        mCallbacks = new TestCallbacks();
-
-        mInputDelegate = new TouchInputHandler(
-                mSelectionMgr,
-                mDetailsLookup,
-                mSelectionPredicate,
-                mGestureStarted,
-                mCallbacks);
-    }
-
-    @Test
-    public void testTap_ActivatesWhenNoExistingSelection() {
-        ItemDetails doc = mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(TAP);
-
-        mCallbacks.assertActivated(doc);
-    }
-
-    @Test
-    public void testScroll_shouldNotBeTrapped() {
-        assertFalse(mInputDelegate.onScroll(null, TAP, -1, -1));
-    }
-
-    @Test
-    public void testLongPress_SelectsItem() {
-        mSelectionPredicate.setReturnValue(true);
-
-        mDetailsLookup.initAt(7);
-        mInputDelegate.onLongPress(TAP);
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testLongPress_StartsGestureSelection() {
-        mSelectionPredicate.setReturnValue(true);
-
-        mDetailsLookup.initAt(7);
-        mInputDelegate.onLongPress(TAP);
-        mGestureStarted.assertRan();
-    }
-
-    @Test
-    public void testSelectHotspot_StartsSelectionMode() {
-        mSelectionPredicate.setReturnValue(true);
-
-        mDetailsLookup.initAt(7).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapUp(TAP);
-
-        mSelection.assertSelection(7);
-    }
-
-    @Test
-    public void testSelectionHotspot_UnselectsSelectedItem() {
-        mSelectionMgr.select("11");
-
-        mDetailsLookup.initAt(11).setInItemSelectRegion(true);
-        mInputDelegate.onSingleTapUp(TAP);
-
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testStartsSelection_PerformsHapticFeedback() {
-        mSelectionPredicate.setReturnValue(true);
-
-        mDetailsLookup.initAt(7);
-        mInputDelegate.onLongPress(TAP);
-
-        mCallbacks.assertVibrated();
-    }
-
-    @Test
-    public void testLongPress_AddsToSelection() {
-        mSelectionPredicate.setReturnValue(true);
-
-        mDetailsLookup.initAt(7);
-        mInputDelegate.onLongPress(TAP);
-
-        mDetailsLookup.initAt(99);
-        mInputDelegate.onLongPress(TAP);
-
-        mDetailsLookup.initAt(13);
-        mInputDelegate.onLongPress(TAP);
-
-        mSelection.assertSelection(7, 13, 99);
-    }
-
-    @Test
-    public void testTap_UnselectsSelectedItem() {
-        mSelectionMgr.select("11");
-
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(TAP);
-
-        mSelection.assertNoSelection();
-    }
-
-    @Test
-    public void testTapOff_ClearsSelection() {
-        mSelectionMgr.select("7");
-        mDetailsLookup.initAt(7);
-
-        mInputDelegate.onLongPress(TAP);
-
-        mSelectionMgr.select("11");
-        mDetailsLookup.initAt(11);
-        mInputDelegate.onSingleTapUp(TAP);
-
-        mDetailsLookup.initAt(RecyclerView.NO_POSITION).setInItemSelectRegion(false);
-        mInputDelegate.onSingleTapUp(TAP);
-
-        mSelection.assertNoSelection();
-    }
-
-    private static final class TestCallbacks extends TouchInputHandler.Callbacks {
-
-        private @Nullable ItemDetails mActivated;
-        private boolean mVibrated;
-
-        @Override
-        public boolean onItemActivated(ItemDetails item, MotionEvent e) {
-            mActivated = item;
-            return false;
-        }
-
-        @Override
-        public boolean onDragInitiated(MotionEvent e) {
-            return false;
-        }
-
-        @Override
-        public void onPerformHapticFeedback() {
-            mVibrated = true;
-        }
-
-        private void assertActivated(ItemDetails expected) {
-            assertEquals(expected, mActivated);
-        }
-
-        private void assertVibrated() {
-            assertTrue(mVibrated);
-        }
-    }
-
-    private static final class TestRunnable implements Runnable {
-
-        private boolean mWasRun;
-
-        @Override
-        public void run() {
-            mWasRun = true;
-        }
-
-        void assertRan() {
-            assertTrue(mWasRun);
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/SelectionHelpers.java b/tests/unit/com/android/documentsui/selection/testing/SelectionHelpers.java
deleted file mode 100644
index 6bdd18a..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/SelectionHelpers.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection.testing;
-
-import com.android.documentsui.selection.DefaultSelectionHelper;
-import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode;
-import com.android.documentsui.selection.SelectionHelper;
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-
-import java.util.Collections;
-import java.util.List;
-
-public class SelectionHelpers {
-
-    public static final SelectionPredicate CAN_SET_ANYTHING = new SelectionPredicate() {
-        @Override
-        public boolean canSetStateForId(String id, boolean nextState) {
-            return true;
-        }
-
-        @Override
-        public boolean canSetStateAtPosition(int position, boolean nextState) {
-            return true;
-        }
-    };
-
-    private SelectionHelpers() {}
-
-    public static SelectionHelper createTestInstance() {
-        return createTestInstance(Collections.emptyList());
-    }
-
-    public static SelectionHelper createTestInstance(List<String> docs) {
-        return createTestInstance(docs, DefaultSelectionHelper.MODE_MULTIPLE);
-    }
-
-    public static SelectionHelper createTestInstance(
-            List<String> items, @SelectionMode int mode) {
-        return createTestInstance(new TestAdapter(items), mode, CAN_SET_ANYTHING);
-    }
-
-    public static SelectionHelper createTestInstance(
-            TestAdapter adapter, @SelectionMode int mode, SelectionPredicate selPredicate) {
-        return new DefaultSelectionHelper(
-                mode, adapter, new TestStableIdProvider(adapter), selPredicate);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/SelectionPredicates.java b/tests/unit/com/android/documentsui/selection/testing/SelectionPredicates.java
deleted file mode 100644
index 0200919..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/SelectionPredicates.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-
-/**
- * Test friendly {@link SelectionPredicate} instances.
- */
-public final class SelectionPredicates {
-
-    private SelectionPredicates() {}
-
-    public static final SelectionPredicate CAN_SET_ANYTHING = new SelectionPredicate() {
-        @Override
-        public boolean canSetStateForId(String id, boolean nextState) {
-            return true;
-        }
-
-        @Override
-        public boolean canSetStateAtPosition(int position, boolean nextState) {
-            return true;
-        }
-    };
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/SelectionProbe.java b/tests/unit/com/android/documentsui/selection/testing/SelectionProbe.java
deleted file mode 100644
index 4d5790b..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/SelectionProbe.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection.testing;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.documentsui.selection.DefaultSelectionHelper;
-import com.android.documentsui.selection.Selection;
-import com.android.documentsui.selection.SelectionHelper;
-
-/**
- * Helper class for making assertions against the state of a {@link DefaultSelectionHelper} instance
- * and the consistency of states between {@link DefaultSelectionHelper} and
- * {@link DefaultSelectionHelper.ItemEventCallback}.
- */
-public final class SelectionProbe {
-
-    private final SelectionHelper mMgr;
-    private final TestSelectionObserver mSelectionListener;
-
-    public SelectionProbe(SelectionHelper mgr) {
-        mMgr = mgr;
-        mSelectionListener = new TestSelectionObserver();
-        mMgr.addObserver(mSelectionListener);
-    }
-
-    public SelectionProbe(SelectionHelper mgr, TestSelectionObserver selectionListener) {
-        mMgr = mgr;
-        mSelectionListener = selectionListener;
-    }
-
-    public void assertRangeSelected(int begin, int end) {
-        for (int i = begin; i <= end; i++) {
-            assertSelected(i);
-        }
-    }
-
-    public void assertRangeNotSelected(int begin, int end) {
-        for (int i = begin; i <= end; i++) {
-            assertNotSelected(i);
-        }
-    }
-
-    public void assertRangeSelection(int begin, int end) {
-        assertSelectionSize(end - begin + 1);
-        assertRangeSelected(begin, end);
-    }
-
-    public void assertSelectionSize(int expected) {
-        Selection selection = mMgr.getSelection();
-        assertEquals(selection.toString(), expected, selection.size());
-
-        mSelectionListener.assertSelectionSize(expected);
-    }
-
-    public void assertNoSelection() {
-        assertSelectionSize(0);
-
-        mSelectionListener.assertNoSelection();
-    }
-
-    public void assertSelection(int... ids) {
-        assertSelected(ids);
-        assertEquals(ids.length, mMgr.getSelection().size());
-
-        mSelectionListener.assertSelectionSize(ids.length);
-    }
-
-    public void assertSelected(int... ids) {
-        Selection sel = mMgr.getSelection();
-        for (int id : ids) {
-            String sid = String.valueOf(id);
-            assertTrue(sid + " is not in selection " + sel, sel.contains(sid));
-
-            mSelectionListener.assertSelected(sid);
-        }
-    }
-
-    public void assertNotSelected(int... ids) {
-        Selection sel = mMgr.getSelection();
-        for (int id : ids) {
-            String sid = String.valueOf(id);
-            assertFalse(sid + " is in selection " + sel, sel.contains(sid));
-
-            mSelectionListener.assertNotSelected(sid);
-        }
-    }
-
-    public void select(int...positions) {
-        for (int position : positions) {
-            mMgr.select(String.valueOf(position));
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestAdapter.java b/tests/unit/com/android/documentsui/selection/testing/TestAdapter.java
deleted file mode 100644
index f4c6d17..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestAdapter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import static org.junit.Assert.assertTrue;
-
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.Adapter;
-import android.support.v7.widget.RecyclerView.AdapterDataObserver;
-import android.view.ViewGroup;
-
-import com.android.documentsui.selection.SelectionHelper;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class TestAdapter extends Adapter<TestHolder> {
-
-    private final List<String> mItems = new ArrayList<>();
-    private final List<Integer> mNotifiedOfSelection = new ArrayList<>();
-    private final AdapterDataObserver mAdapterObserver;
-
-    public TestAdapter() {
-        this(Collections.EMPTY_LIST);
-    }
-
-    public TestAdapter(List<String> items) {
-        mItems.addAll(items);
-        mAdapterObserver = new RecyclerView.AdapterDataObserver() {
-
-            @Override
-            public void onChanged() {
-            }
-
-            @Override
-            public void onItemRangeChanged(int startPosition, int itemCount, Object payload) {
-                if (SelectionHelper.SELECTION_CHANGED_MARKER.equals(payload)) {
-                    int last = startPosition + itemCount;
-                    for (int i = startPosition; i < last; i++) {
-                        mNotifiedOfSelection.add(i);
-                    }
-                }
-            }
-
-            @Override
-            public void onItemRangeInserted(int startPosition, int itemCount) {
-            }
-
-            @Override
-            public void onItemRangeRemoved(int startPosition, int itemCount) {
-            }
-
-            @Override
-            public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
-                throw new UnsupportedOperationException();
-            }
-        };
-
-        registerAdapterDataObserver(mAdapterObserver);
-    }
-
-    @Override
-    public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        return new TestHolder(parent);
-    }
-
-    @Override
-    public void onBindViewHolder(TestHolder holder, int position) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getItemCount() {
-        return mItems.size();
-    }
-
-    public void updateTestModelIds(List<String> items) {
-        mItems.clear();
-        mItems.addAll(items);
-
-        notifyDataSetChanged();
-    }
-
-    public List<String> getStableIds() {
-        return mItems;
-    }
-
-    public int getPosition(String id) {
-        return mItems.indexOf(id);
-    }
-
-    public String getStableId(int position) {
-        return mItems.get(position);
-    }
-
-
-    public void resetSelectionNotifications() {
-        mNotifiedOfSelection.clear();
-    }
-
-    public void assertNotifiedOfSelectionChange(int position) {
-        assertTrue(mNotifiedOfSelection.contains(position));
-    }
-
-    public static List<String> createItemList(int num) {
-        List<String> items = new ArrayList<>(num);
-        for (int i = 0; i < num; ++i) {
-            items.add(Integer.toString(i));
-        }
-        return items;
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestBandPredicate.java b/tests/unit/com/android/documentsui/selection/testing/TestBandPredicate.java
deleted file mode 100644
index 2e901a0..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestBandPredicate.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.BandPredicate;
-
-public class TestBandPredicate extends BandPredicate {
-
-    private boolean mCanInitiate = true;
-
-    public void setCanInitiate(boolean canInitiate) {
-        mCanInitiate = canInitiate;
-    }
-
-    @Override
-    public boolean canInitiate(MotionEvent e) {
-        return mCanInitiate;
-    }
-
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestData.java b/tests/unit/com/android/documentsui/selection/testing/TestData.java
deleted file mode 100644
index 1a05990..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestData.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection.testing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TestData {
-    public static List<String> create(int num) {
-        List<String> items = new ArrayList<String>(num);
-        for (int i = 0; i < num; ++i) {
-            items.add(Integer.toString(i));
-        }
-        return items;
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestEvents.java b/tests/unit/com/android/documentsui/selection/testing/TestEvents.java
deleted file mode 100644
index c472adb..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestEvents.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2016 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.documentsui.selection.testing;
-
-import android.annotation.IntDef;
-import android.graphics.Point;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Handy-dandy wrapper class to facilitate the creation of MotionEvents.
- */
-public final class TestEvents {
-
-    /**
-     * Common mouse event types...for your convenience.
-     */
-    public static final class Mouse {
-        public static final MotionEvent CLICK =
-                TestEvents.builder().mouse().primary().build();
-        public static final MotionEvent CTRL_CLICK =
-                TestEvents.builder().mouse().primary().ctrl().build();
-        public static final MotionEvent ALT_CLICK =
-                TestEvents.builder().mouse().primary().alt().build();
-        public static final MotionEvent SHIFT_CLICK =
-                TestEvents.builder().mouse().primary().shift().build();
-        public static final MotionEvent SECONDARY_CLICK =
-                TestEvents.builder().mouse().secondary().build();
-        public static final MotionEvent TERTIARY_CLICK =
-                TestEvents.builder().mouse().tertiary().build();
-    }
-
-    /**
-     * Common touch event types...for your convenience.
-     */
-    public static final class Touch {
-        public static final MotionEvent TAP =
-                TestEvents.builder().touch().build();
-    }
-
-    static final int ACTION_UNSET = -1;
-
-    // Add other actions from MotionEvent.ACTION_ as needed.
-    @IntDef(flag = true, value = {
-            MotionEvent.ACTION_DOWN,
-            MotionEvent.ACTION_MOVE,
-            MotionEvent.ACTION_UP
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Action {}
-
-    // Add other types from MotionEvent.TOOL_TYPE_ as needed.
-    @IntDef(flag = true, value = {
-            MotionEvent.TOOL_TYPE_FINGER,
-            MotionEvent.TOOL_TYPE_MOUSE,
-            MotionEvent.TOOL_TYPE_STYLUS,
-            MotionEvent.TOOL_TYPE_UNKNOWN
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ToolType {}
-
-    @IntDef(flag = true, value = {
-            MotionEvent.BUTTON_PRIMARY,
-            MotionEvent.BUTTON_SECONDARY
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Button {}
-
-    @IntDef(flag = true, value = {
-            KeyEvent.META_SHIFT_ON,
-            KeyEvent.META_CTRL_ON
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Key {}
-
-    private static final class State {
-        private @Action int mAction = ACTION_UNSET;
-        private @ToolType int mToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
-        private int mPointerCount = 1;
-        private Set<Integer> mButtons = new HashSet<>();
-        private Set<Integer> mKeys = new HashSet<>();
-        private Point mLocation = new Point(0, 0);
-        private Point mRawLocation = new Point(0, 0);
-    }
-
-    public static final Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Test event builder with convenience methods for common event attrs.
-     */
-    public static final class Builder {
-
-        private State mState = new State();
-
-        /**
-         * @param action Any action specified in {@link MotionEvent}.
-         * @return
-         */
-        public Builder action(int action) {
-            mState.mAction = action;
-            return this;
-        }
-
-        public Builder type(@ToolType int type) {
-            mState.mToolType = type;
-            return this;
-        }
-
-        public Builder location(int x, int y) {
-            mState.mLocation = new Point(x, y);
-            return this;
-        }
-
-        public Builder rawLocation(int x, int y) {
-            mState.mRawLocation = new Point(x, y);
-            return this;
-        }
-
-        public Builder pointerCount(int count) {
-            mState.mPointerCount = count;
-            return this;
-        }
-
-        /**
-         * Adds one or more button press attributes.
-         */
-        public Builder pressButton(@Button int... buttons) {
-            for (int button : buttons) {
-                mState.mButtons.add(button);
-            }
-            return this;
-        }
-
-        /**
-         * Removes one or more button press attributes.
-         */
-        public Builder releaseButton(@Button int... buttons) {
-            for (int button : buttons) {
-                mState.mButtons.remove(button);
-            }
-            return this;
-        }
-
-        /**
-         * Adds one or more key press attributes.
-         */
-        public Builder pressKey(@Key int... keys) {
-            for (int key : keys) {
-                mState.mKeys.add(key);
-            }
-            return this;
-        }
-
-        /**
-         * Removes one or more key press attributes.
-         */
-        public Builder releaseKey(@Button int... keys) {
-            for (int key : keys) {
-                mState.mKeys.remove(key);
-            }
-            return this;
-        }
-
-        public Builder touch() {
-            type(MotionEvent.TOOL_TYPE_FINGER);
-            return this;
-        }
-
-        public Builder mouse() {
-            type(MotionEvent.TOOL_TYPE_MOUSE);
-            return this;
-        }
-
-        public Builder shift() {
-            pressKey(KeyEvent.META_SHIFT_ON);
-            return this;
-        }
-
-        /**
-         * Use {@link #remove(@Attribute int...)}
-         */
-        public Builder unshift() {
-            releaseKey(KeyEvent.META_SHIFT_ON);
-            return this;
-        }
-
-        public Builder ctrl() {
-            pressKey(KeyEvent.META_CTRL_ON);
-            return this;
-        }
-
-        public Builder alt() {
-            pressKey(KeyEvent.META_ALT_ON);
-            return this;
-        }
-
-        public Builder primary() {
-            pressButton(MotionEvent.BUTTON_PRIMARY);
-            releaseButton(MotionEvent.BUTTON_SECONDARY);
-            releaseButton(MotionEvent.BUTTON_TERTIARY);
-            return this;
-        }
-
-        public Builder secondary() {
-            pressButton(MotionEvent.BUTTON_SECONDARY);
-            releaseButton(MotionEvent.BUTTON_PRIMARY);
-            releaseButton(MotionEvent.BUTTON_TERTIARY);
-            return this;
-        }
-
-        public Builder tertiary() {
-            pressButton(MotionEvent.BUTTON_TERTIARY);
-            releaseButton(MotionEvent.BUTTON_PRIMARY);
-            releaseButton(MotionEvent.BUTTON_SECONDARY);
-            return this;
-        }
-
-        public MotionEvent build() {
-
-            PointerProperties[] pointers = new PointerProperties[1];
-            pointers[0] = new PointerProperties();
-            pointers[0].id = 0;
-            pointers[0].toolType = mState.mToolType;
-
-            PointerCoords[] coords = new PointerCoords[1];
-            coords[0] = new PointerCoords();
-            coords[0].x = mState.mLocation.x;
-            coords[0].y = mState.mLocation.y;
-
-            int buttons = 0;
-            for (Integer button : mState.mButtons) {
-                buttons |= button;
-            }
-
-            int keys = 0;
-            for (Integer key : mState.mKeys) {
-                keys |= key;
-            }
-
-            return MotionEvent.obtain(
-                    0,     // down time
-                    1,     // event time
-                    mState.mAction,
-                    1,  // pointerCount,
-                    pointers,
-                    coords,
-                    keys,
-                    buttons,
-                    1.0f,  // x precision
-                    1.0f,  // y precision
-                    0,     // device id
-                    0,     // edge flags
-                    0,     // int source,
-                    0      // int flags
-                    );
-        }
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestHolder.java b/tests/unit/com/android/documentsui/selection/testing/TestHolder.java
deleted file mode 100644
index a0728fe..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestHolder.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.view.View;
-
-public class TestHolder extends ViewHolder {
-    public TestHolder(View itemView) {
-        super(itemView);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestMouseCallbacks.java b/tests/unit/com/android/documentsui/selection/testing/TestMouseCallbacks.java
deleted file mode 100644
index 06edc1e..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestMouseCallbacks.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.support.v7.widget.RecyclerView;
-import android.view.MotionEvent;
-
-import com.android.documentsui.selection.MouseInputHandler;
-import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
-
-public final class TestMouseCallbacks extends MouseInputHandler.Callbacks {
-
-    private String mFocusItemId;
-    private int mFocusPosition;
-    private MotionEvent mLastContextEvent;
-    private ItemDetails mActivated;
-
-    @Override
-    public boolean onItemActivated(ItemDetails item, MotionEvent e) {
-        mActivated = item;
-        return true;
-    }
-
-    @Override
-    public boolean onContextClick(MotionEvent e) {
-        mLastContextEvent = e;
-        return false;
-    }
-
-    @Override
-    public void onPerformHapticFeedback() {
-    }
-
-    @Override
-    public void clearFocus() {
-        mFocusPosition = RecyclerView.NO_POSITION;
-        mFocusItemId = null;
-    }
-
-    @Override
-    public void focusItem(ItemDetails item) {
-        mFocusItemId = item.getStableId();
-        mFocusPosition = item.getPosition();
-    }
-
-    @Override
-    public int getFocusedPosition() {
-        return mFocusPosition;
-    }
-
-    @Override
-    public boolean hasFocusedItem() {
-        return mFocusItemId != null;
-    }
-
-    public void assertLastEvent(MotionEvent expected) {
-        // sadly, MotionEvent doesn't implement equals, so we compare references.
-        assertTrue(expected == mLastContextEvent);
-    }
-
-    public void assertActivated(ItemDetails expected) {
-        assertEquals(expected, mActivated);
-    }
-
-    public void assertHasFocus(boolean focused) {
-        assertEquals(focused, hasFocusedItem());
-    }
-
-    public void assertFocused(String expectedId) {
-        assertEquals(expectedId, mFocusItemId);
-    }
-}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestSelectionObserver.java b/tests/unit/com/android/documentsui/selection/testing/TestSelectionObserver.java
deleted file mode 100644
index e75bde3..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestSelectionObserver.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class TestSelectionObserver extends SelectionObserver {
-
-    private final Set<String> mSelected = new HashSet<>();
-    private boolean mSelectionChanged = false;
-    private boolean mSelectionReset = false;
-    private boolean mSelectionRestored = false;
-
-    public void reset() {
-        mSelected.clear();
-        mSelectionChanged = false;
-        mSelectionReset = false;
-    }
-
-    @Override
-    public void onItemStateChanged(String id, boolean selected) {
-        if (selected) {
-            assertNotSelected(id);
-            mSelected.add(id);
-        } else {
-            assertSelected(id);
-            mSelected.remove(id);
-        }
-    }
-
-    @Override
-    public void onSelectionReset() {
-        mSelectionReset = true;
-        mSelected.clear();
-    }
-
-    @Override
-    public void onSelectionChanged() {
-        mSelectionChanged = true;
-    }
-
-    @Override
-    public void onSelectionRestored() {
-        mSelectionRestored = true;
-    }
-
-    void assertNoSelection() {
-        assertTrue(mSelected.isEmpty());
-    }
-
-    void assertSelectionSize(int expected) {
-        assertEquals(expected, mSelected.size());
-    }
-
-    void assertSelected(String id) {
-        assertTrue(id + " is not selected.", mSelected.contains(id));
-    }
-
-    void assertNotSelected(String id) {
-        assertFalse(id + " is already selected", mSelected.contains(id));
-    }
-
-    public void assertSelectionChanged() {
-        assertTrue(mSelectionChanged);
-    }
-
-    public void assertSelectionUnchanged() {
-        assertFalse(mSelectionChanged);
-    }
-
-    public void assertSelectionReset() {
-        assertTrue(mSelectionReset);
-    }
-
-    public void assertSelectionRestored() {
-        assertTrue(mSelectionRestored);
-    }
-}
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestSelectionPredicate.java b/tests/unit/com/android/documentsui/selection/testing/TestSelectionPredicate.java
deleted file mode 100644
index 578be3d..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestSelectionPredicate.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import com.android.documentsui.selection.SelectionHelper.SelectionPredicate;
-
-public final class TestSelectionPredicate extends SelectionPredicate {
-    private boolean mValue;
-
-    public void setReturnValue(boolean value) {
-        mValue = value;
-    }
-
-    @Override
-    public boolean canSetStateForId(String id, boolean nextState) {
-        return mValue;
-    }
-
-    @Override
-    public boolean canSetStateAtPosition(int position, boolean nextState) {
-        return mValue;
-    }
-}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/selection/testing/TestStableIdProvider.java b/tests/unit/com/android/documentsui/selection/testing/TestStableIdProvider.java
deleted file mode 100644
index 1d50737..0000000
--- a/tests/unit/com/android/documentsui/selection/testing/TestStableIdProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2017 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.documentsui.selection.testing;
-
-import static android.support.v4.util.Preconditions.checkArgument;
-
-import com.android.documentsui.selection.SelectionHelper.StableIdProvider;
-
-import java.util.List;
-
-/**
- * Provides RecyclerView selection code access to stable ids backed
- * by TestAdapter.
- */
-public final class TestStableIdProvider extends StableIdProvider {
-
-    private final TestAdapter mAdapter;
-
-    public TestStableIdProvider(TestAdapter adapter) {
-        checkArgument(adapter != null);
-        mAdapter = adapter;
-    }
-
-    @Override
-    public String getStableId(int position) {
-        return mAdapter.getStableId(position);
-    }
-
-    @Override
-    public int getPosition(String id) {
-        return mAdapter.getPosition(id);
-    }
-
-    @Override
-    public List<String> getStableIds() {
-        return mAdapter.getStableIds();
-    }
-}
diff --git a/tests/unit/com/android/documentsui/services/AbstractCopyJobTest.java b/tests/unit/com/android/documentsui/services/AbstractCopyJobTest.java
index a02a51d..7ebd3b7 100644
--- a/tests/unit/com/android/documentsui/services/AbstractCopyJobTest.java
+++ b/tests/unit/com/android/documentsui/services/AbstractCopyJobTest.java
@@ -18,14 +18,21 @@
 
 import static com.google.common.collect.Lists.newArrayList;
 
+import static org.junit.Assert.assertNotEquals;
+
+import android.app.Notification;
 import android.net.Uri;
 import android.provider.DocumentsContract;
 import android.test.suitebuilder.annotation.MediumTest;
+import android.text.format.DateUtils;
 
+import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.services.FileOperationService.OpType;
 
+import java.text.NumberFormat;
 import java.util.List;
+import java.util.stream.IntStream;
 
 @MediumTest
 public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJobTest<T> {
@@ -84,9 +91,17 @@
     public void runCopyEmptyDirTest() throws Exception {
         Uri testDir = mDocs.createFolder(mSrcRoot, "emptyDir");
 
-        createJob(newArrayList(testDir)).run();
+        CopyJob job = createJob(newArrayList(testDir));
+        job.run();
         waitForJobFinished();
 
+        Notification progressNotification = job.getProgressNotification();
+        String copyPercentage = progressNotification.extras.getString(Notification.EXTRA_SUB_TEXT);
+
+        // the percentage representation should not be NaN.
+        assertNotEquals(copyPercentage.equals(NumberFormat.getPercentInstance().format(Double.NaN)),
+                "Percentage representation should not be NaN.");
+
         mDocs.assertChildCount(mDestRoot, 1);
         mDocs.assertHasDirectory(mDestRoot, "emptyDir");
     }
@@ -160,6 +175,74 @@
         mDocs.assertChildCount(mDestRoot, 0);
     }
 
+    public void runCopyProgressForFileCountTest() throws Exception {
+        // Init FileCountProgressTracker with 10 docs required to copy.
+        TestCopyJobProcessTracker<CopyJob.FileCountProgressTracker> tracker =
+                new TestCopyJobProcessTracker(CopyJob.FileCountProgressTracker.class, 10,
+                        createJob(newArrayList(mDocs.createFolder(mSrcRoot, "dummyDir"))),
+                        (completed) -> NumberFormat.getPercentInstance().format(completed),
+                        (time) -> mContext.getString(R.string.copy_remaining,
+                                DateUtils.formatDuration((Long) time)));
+
+        // Assert init progress is 0 & default remaining time is -1.
+        tracker.getProcessTracker().start();
+        tracker.assertProgressTrackStarted();
+        tracker.assertStartedProgressEquals(0);
+        tracker.assertStartedRemainingTimeEquals(-1);
+
+        // Progress 20%: 2 docs processed after 1 sec, no remaining time since first sample.
+        IntStream.range(0, 2).forEach(__ -> tracker.getProcessTracker().onDocumentCompleted());
+        tracker.updateProgressAndRemainingTime(1000);
+        tracker.assertProgressEquals(0.2);
+        tracker.assertNoRemainingTime();
+
+        // Progress 40%: 4 docs processed after 2 secs, expect remaining time is 3 secs.
+        IntStream.range(2, 4).forEach(__ -> tracker.getProcessTracker().onDocumentCompleted());
+        tracker.updateProgressAndRemainingTime(2000);
+        tracker.assertProgressEquals(0.4);
+        tracker.assertReminingTimeEquals(3000L);
+
+        // progress 100%: 10 doc processed after 5 secs, expect no remaining time shown.
+        IntStream.range(4, 10).forEach(__ -> tracker.getProcessTracker().onDocumentCompleted());
+        tracker.updateProgressAndRemainingTime(5000);
+        tracker.assertProgressEquals(1.0);
+        tracker.assertNoRemainingTime();
+    }
+
+    public void runCopyProgressForByteCountTest() throws Exception {
+        // Init ByteCountProgressTracker with 100 KBytes required to copy.
+        TestCopyJobProcessTracker<CopyJob.ByteCountProgressTracker> tracker =
+                new TestCopyJobProcessTracker(CopyJob.ByteCountProgressTracker.class, 100000,
+                        createJob(newArrayList(mDocs.createFolder(mSrcRoot, "dummyDir"))),
+                        (completed) -> NumberFormat.getPercentInstance().format(completed),
+                        (time) -> mContext.getString(R.string.copy_remaining,
+                                DateUtils.formatDuration((Long) time)));
+
+        // Assert init progress is 0 & default remaining time is -1.
+        tracker.getProcessTracker().start();
+        tracker.assertProgressTrackStarted();
+        tracker.assertStartedProgressEquals(0);
+        tracker.assertStartedRemainingTimeEquals(-1);
+
+        // Progress 25%: 25 KBytes processed after 1 sec, no remaining time since first sample.
+        tracker.getProcessTracker().onBytesCopied(25000);
+        tracker.updateProgressAndRemainingTime(1000);
+        tracker.assertProgressEquals(0.25);
+        tracker.assertNoRemainingTime();
+
+        // Progress 50%: 50 KBytes processed after 2 secs, expect remaining time is 2 secs.
+        tracker.getProcessTracker().onBytesCopied(25000);
+        tracker.updateProgressAndRemainingTime(2000);
+        tracker.assertProgressEquals(0.5);
+        tracker.assertReminingTimeEquals(2000L);
+
+        // Progress 100%: 100 KBytes processed after 4 secs, expect no remaining time shown.
+        tracker.getProcessTracker().onBytesCopied(50000);
+        tracker.updateProgressAndRemainingTime(4000);
+        tracker.assertProgressEquals(1.0);
+        tracker.assertNoRemainingTime();
+    }
+
     void waitForJobFinished() throws Exception {
         mJobListener.waitForFinished();
         mDocs.waitForWrite();
diff --git a/tests/unit/com/android/documentsui/services/AbstractJobTest.java b/tests/unit/com/android/documentsui/services/AbstractJobTest.java
index 7ca913d..bb29daa 100644
--- a/tests/unit/com/android/documentsui/services/AbstractJobTest.java
+++ b/tests/unit/com/android/documentsui/services/AbstractJobTest.java
@@ -24,10 +24,11 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
 import android.test.AndroidTestCase;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+
 import com.android.documentsui.DocumentsProviderHelper;
 import com.android.documentsui.R;
 import com.android.documentsui.StubProvider;
@@ -94,6 +95,30 @@
         mDestRoot = mDocs.getRoot(ROOT_1_ID);
     }
 
+    FileOperation createOperation(@OpType int opType, List<Uri> srcs, Uri srcParent,
+            Uri destination) throws Exception {
+        DocumentStack stack =
+                new DocumentStack(mSrcRoot, DocumentInfo.fromUri(mResolver, destination));
+
+        UrisSupplier urisSupplier = DocsProviders.createDocsProvider(srcs);
+        FileOperation operation = new FileOperation.Builder()
+                .withOpType(opType)
+                .withSrcs(urisSupplier)
+                .withDestination(stack)
+                .withSrcParent(srcParent)
+                .build();
+        return operation;
+    }
+
+    final T createJob(FileOperation operation) {
+        return createJob(operation, mJobListener);
+    }
+
+    final T createJob(FileOperation operation, Job.Listener listener) {
+        return (T) operation.createJob(
+                mContext, listener, FileOperations.createJobId(), mFeatures);
+    }
+
     final T createJob(@OpType int opType, List<Uri> srcs, Uri srcParent, Uri destination)
             throws Exception {
         DocumentStack stack =
diff --git a/tests/unit/com/android/documentsui/services/CopyJobTest.java b/tests/unit/com/android/documentsui/services/CopyJobTest.java
index afdd855..8d98b27 100644
--- a/tests/unit/com/android/documentsui/services/CopyJobTest.java
+++ b/tests/unit/com/android/documentsui/services/CopyJobTest.java
@@ -17,12 +17,12 @@
 package com.android.documentsui.services;
 
 import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
-
 import static com.google.common.collect.Lists.newArrayList;
 
 import android.net.Uri;
 import android.provider.DocumentsContract.Document;
-import android.support.test.filters.MediumTest;
+
+import androidx.test.filters.MediumTest;
 
 @MediumTest
 public class CopyJobTest extends AbstractCopyJobTest<CopyJob> {
@@ -82,4 +82,12 @@
     public void testCopyFileWithReadErrors() throws Exception {
         runCopyFileWithReadErrorsTest();
     }
+
+    public void testCopyProgressWithFileCount() throws Exception {
+        runCopyProgressForFileCountTest();
+    }
+
+    public void testCopyProgressWithByteCount() throws Exception {
+        runCopyProgressForByteCountTest();
+    }
 }
diff --git a/tests/unit/com/android/documentsui/services/DeleteJobTest.java b/tests/unit/com/android/documentsui/services/DeleteJobTest.java
index 0d8d39b..a200b3e 100644
--- a/tests/unit/com/android/documentsui/services/DeleteJobTest.java
+++ b/tests/unit/com/android/documentsui/services/DeleteJobTest.java
@@ -17,12 +17,12 @@
 package com.android.documentsui.services;
 
 import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
-
 import static com.google.common.collect.Lists.newArrayList;
 
 import android.net.Uri;
 import android.provider.DocumentsContract;
-import android.support.test.filters.MediumTest;
+
+import androidx.test.filters.MediumTest;
 
 import java.util.List;
 
diff --git a/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java b/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java
index fbaafe8..9670747 100644
--- a/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java
+++ b/tests/unit/com/android/documentsui/services/FileOperationServiceTest.java
@@ -20,7 +20,7 @@
 import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
 import static com.android.documentsui.services.FileOperations.createBaseIntent;
 import static com.android.documentsui.services.FileOperations.createJobId;
-import static com.google.android.collect.Lists.newArrayList;
+
 import static org.junit.Assert.fail;
 
 import android.content.Context;
@@ -28,10 +28,11 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
 import android.test.ServiceTestCase;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.DocumentStack;
@@ -44,6 +45,7 @@
 import com.android.documentsui.testing.TestScheduledExecutorService;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 @MediumTest
@@ -121,8 +123,8 @@
     }
 
     public void testRunsCopyJobs() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mExecutor.runAll();
         assertAllCopyJobsStarted();
@@ -135,7 +137,7 @@
         } catch(IllegalArgumentException expected) {
             // We're sending a naughty empty list that should result in an IllegalArgumentException.
         }
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         assertJobsCreated(1);
 
@@ -144,8 +146,8 @@
     }
 
     public void testRunsCopyJobs_AfterFailure() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mCopyJobs.get(0).fail(ALPHA_DOC);
 
@@ -154,30 +156,30 @@
     }
 
     public void testRunsCopyJobs_notRunsDeleteJobs() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createDeleteIntent(newArrayList(GAMMA_DOC)));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createDeleteIntent(Arrays.asList(GAMMA_DOC)));
 
         mExecutor.runAll();
         assertNoDeleteJobsStarted();
     }
 
     public void testRunsDeleteJobs() throws Exception {
-        startService(createDeleteIntent(newArrayList(ALPHA_DOC)));
+        startService(createDeleteIntent(Arrays.asList(ALPHA_DOC)));
 
         mDeletionExecutor.runAll();
         assertAllDeleteJobsStarted();
     }
 
     public void testRunsDeleteJobs_NotRunsCopyJobs() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createDeleteIntent(newArrayList(GAMMA_DOC)));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createDeleteIntent(Arrays.asList(GAMMA_DOC)));
 
         mDeletionExecutor.runAll();
         assertNoCopyJobsStarted();
     }
 
     public void testUpdatesNotification() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
         mExecutor.runAll();
 
         // Assert monitoring continues until job is done
@@ -187,7 +189,7 @@
     }
 
     public void testStopsUpdatingNotificationAfterFinished() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
         mExecutor.runAll();
 
         mHandler.dispatchNextMessage();
@@ -200,13 +202,13 @@
     }
 
     public void testHoldsWakeLockWhileWorking() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
 
         assertTrue(mService.holdsWakeLock());
     }
 
     public void testReleasesWakeLock_AfterSuccess() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
 
         assertTrue(mService.holdsWakeLock());
         mExecutor.runAll();
@@ -214,7 +216,7 @@
     }
 
     public void testReleasesWakeLock_AfterFailure() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
 
         assertTrue(mService.holdsWakeLock());
         mExecutor.runAll();
@@ -222,7 +224,7 @@
     }
 
     public void testShutdownStopsExecutor_AfterSuccess() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
 
         mExecutor.assertAlive();
         mDeletionExecutor.assertAlive();
@@ -234,8 +236,8 @@
     }
 
     public void testShutdownStopsExecutor_AfterMixedFailures() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mCopyJobs.get(0).fail(ALPHA_DOC);
 
@@ -246,8 +248,8 @@
     }
 
     public void testShutdownStopsExecutor_AfterTotalFailure() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mCopyJobs.get(0).fail(ALPHA_DOC);
         mCopyJobs.get(1).fail(GAMMA_DOC);
@@ -259,8 +261,8 @@
     }
 
     public void testRunsInForeground_MultipleJobs() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mExecutor.run(0);
         mForegroundManager.assertInForeground();
@@ -270,8 +272,8 @@
     }
 
     public void testFinishesInBackground_MultipleJobs() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mExecutor.run(0);
         mForegroundManager.assertInForeground();
@@ -285,8 +287,8 @@
     }
 
     public void testAllNotificationsDismissedAfterShutdown() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
 
         mExecutor.runAll();
 
@@ -295,8 +297,8 @@
     }
 
     public void testNotificationUpdateAfterForegroundJobSwitch() throws Exception {
-        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
-        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+        startService(createCopyIntent(Arrays.asList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(Arrays.asList(GAMMA_DOC), DELTA_DOC));
         Job job1 = mCopyJobs.get(0);
         Job job2 = mCopyJobs.get(1);
 
@@ -320,7 +322,7 @@
         mTestNotificationManager.assertNumberOfNotifications(0);
     }
 
-    private Intent createCopyIntent(ArrayList<DocumentInfo> files, DocumentInfo dest)
+    private Intent createCopyIntent(List<DocumentInfo> files, DocumentInfo dest)
             throws Exception {
         DocumentStack stack = new DocumentStack();
         stack.push(dest);
@@ -336,7 +338,7 @@
         return createBaseIntent(getContext(), createJobId(), operation);
     }
 
-    private Intent createDeleteIntent(ArrayList<DocumentInfo> files) {
+    private Intent createDeleteIntent(List<DocumentInfo> files) {
         DocumentStack stack = new DocumentStack();
 
         List<Uri> uris = new ArrayList<>(files.size());
@@ -388,6 +390,7 @@
     void assertJobsCreated(int expected) {
         assertEquals(expected, mCopyJobs.size() + mDeleteJobs.size());
     }
+
     private static DocumentInfo createDoc(Uri destination) {
         DocumentInfo destDoc = new DocumentInfo();
         destDoc.derivedUri = destination;
diff --git a/tests/unit/com/android/documentsui/services/JobErrorHandlingTest.java b/tests/unit/com/android/documentsui/services/JobErrorHandlingTest.java
index 89b34bc..680f945 100644
--- a/tests/unit/com/android/documentsui/services/JobErrorHandlingTest.java
+++ b/tests/unit/com/android/documentsui/services/JobErrorHandlingTest.java
@@ -21,7 +21,8 @@
 
 import android.net.Uri;
 import android.provider.DocumentsContract;
-import android.support.test.filters.MediumTest;
+
+import androidx.test.filters.MediumTest;
 
 import java.util.List;
 
diff --git a/tests/unit/com/android/documentsui/services/MoveJobTest.java b/tests/unit/com/android/documentsui/services/MoveJobTest.java
index 37445a6..1fc2fd3 100644
--- a/tests/unit/com/android/documentsui/services/MoveJobTest.java
+++ b/tests/unit/com/android/documentsui/services/MoveJobTest.java
@@ -21,7 +21,8 @@
 
 import android.net.Uri;
 import android.provider.DocumentsContract.Document;
-import android.support.test.filters.MediumTest;
+
+import androidx.test.filters.MediumTest;
 
 @MediumTest
 public class MoveJobTest extends AbstractCopyJobTest<MoveJob> {
diff --git a/tests/unit/com/android/documentsui/sidebar/RootsFragmentTest.java b/tests/unit/com/android/documentsui/sidebar/RootsFragmentTest.java
new file mode 100644
index 0000000..6dd0309
--- /dev/null
+++ b/tests/unit/com/android/documentsui/sidebar/RootsFragmentTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 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.documentsui.sidebar;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.pm.ResolveInfo;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.testing.TestProvidersAccess;
+import com.android.documentsui.testing.TestResolveInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * An unit test for RootsFragment.
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class RootsFragmentTest {
+
+    private RootsFragment mRootsFragment;
+
+    private static final String[] EXPECTED_SORTED_RESULT = {
+            TestProvidersAccess.RECENTS.title,
+            TestProvidersAccess.IMAGE.title,
+            TestProvidersAccess.VIDEO.title,
+            TestProvidersAccess.AUDIO.title,
+            TestProvidersAccess.DOWNLOADS.title,
+            "" /* SpacerItem */,
+            TestProvidersAccess.EXTERNALSTORAGE.title,
+            TestProvidersAccess.HAMMY.title,
+            "" /* SpacerItem */,
+            TestProvidersAccess.INSPECTOR.title,
+            TestProvidersAccess.PICKLES.title};
+
+    @Before
+    public void setUp() {
+        mRootsFragment = new RootsFragment();
+    }
+
+    @Test
+    public void testSortLoadResult_WithCorrectOrder() {
+        List<Item> items = mRootsFragment.sortLoadResult(createFakeRootInfoList(),
+                null /* excludePackage */, null /* handlerAppIntent */, new TestProvidersAccess());
+        assertTrue(assertSortedResult(items));
+    }
+
+    @Test
+    public void testItemComparator_WithCorrectOrder() {
+        final String testPackageName = "com.test1";
+        final String errorTestPackageName = "com.test2";
+        final RootsFragment.ItemComparator comp = new RootsFragment.ItemComparator(testPackageName);
+        final List<Item> rootList = new ArrayList<>();
+        rootList.add(new RootItem(TestProvidersAccess.HAMMY, null /* actionHandler */,
+                errorTestPackageName));
+        rootList.add(new RootItem(TestProvidersAccess.INSPECTOR, null /* actionHandler */,
+                errorTestPackageName));
+        rootList.add(new RootItem(TestProvidersAccess.PICKLES, null /* actionHandler */,
+                testPackageName));
+        Collections.sort(rootList, comp);
+
+        assertEquals(rootList.get(0).title, TestProvidersAccess.PICKLES.title);
+        assertEquals(rootList.get(1).title, TestProvidersAccess.HAMMY.title);
+        assertEquals(rootList.get(2).title, TestProvidersAccess.INSPECTOR.title);
+    }
+
+    @Test
+    public void testItemComparator_differentItemTypes_WithCorrectOrder() {
+        final String testPackageName = "com.test1";
+        final RootsFragment.ItemComparator comp = new RootsFragment.ItemComparator(testPackageName);
+        final List<Item> rootList = new ArrayList<>();
+        rootList.add(new RootItem(TestProvidersAccess.HAMMY, null /* actionHandler */,
+                testPackageName));
+
+        final ResolveInfo info = TestResolveInfo.create();
+        info.activityInfo.packageName = testPackageName;
+
+        rootList.add(new AppItem(info, TestProvidersAccess.PICKLES.title,
+                null /* actionHandler */));
+        rootList.add(new RootAndAppItem(TestProvidersAccess.INSPECTOR, info,
+                null /* actionHandler */));
+
+        Collections.sort(rootList, comp);
+
+        assertEquals(rootList.get(0).title, TestProvidersAccess.HAMMY.title);
+        assertEquals(rootList.get(1).title, TestProvidersAccess.INSPECTOR.title);
+        assertEquals(rootList.get(2).title, TestProvidersAccess.PICKLES.title);
+    }
+
+    private boolean assertSortedResult(List<Item> items) {
+        for (int i = 0; i < items.size(); i++) {
+            Item item = items.get(i);
+            if (item instanceof RootItem) {
+                assertEquals(EXPECTED_SORTED_RESULT[i], ((RootItem) item).root.title);
+            } else if (item instanceof SpacerItem) {
+                assertTrue(EXPECTED_SORTED_RESULT[i].isEmpty());
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private List<RootInfo> createFakeRootInfoList() {
+        final List<RootInfo> fakeRootInfoList = new ArrayList<>();
+        fakeRootInfoList.add(TestProvidersAccess.PICKLES);
+        fakeRootInfoList.add(TestProvidersAccess.HAMMY);
+        fakeRootInfoList.add(TestProvidersAccess.INSPECTOR);
+        fakeRootInfoList.add(TestProvidersAccess.DOWNLOADS);
+        fakeRootInfoList.add(TestProvidersAccess.AUDIO);
+        fakeRootInfoList.add(TestProvidersAccess.VIDEO);
+        fakeRootInfoList.add(TestProvidersAccess.RECENTS);
+        fakeRootInfoList.add(TestProvidersAccess.IMAGE);
+        fakeRootInfoList.add(TestProvidersAccess.EXTERNALSTORAGE);
+        return fakeRootInfoList;
+    }
+}
diff --git a/tests/unit/com/android/documentsui/sorting/SortControllerTest.java b/tests/unit/com/android/documentsui/sorting/SortControllerTest.java
index 9c2cc64..7cc781f 100644
--- a/tests/unit/com/android/documentsui/sorting/SortControllerTest.java
+++ b/tests/unit/com/android/documentsui/sorting/SortControllerTest.java
@@ -18,13 +18,13 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.base.State;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -33,29 +33,19 @@
 public class SortControllerTest {
 
     private TestWidget mTableHeader;
-    private TestWidget mDropHeader;
     private SortController mController;
 
     @Test
-    public void testGridMode_ShowsDrop() {
+    public void testGridMode_hidesTable() {
         createWidget(true);
         mController.onViewModeChanged(State.MODE_GRID);
-        mDropHeader.assertVisible();
         mTableHeader.assertGone();
     }
 
     @Test
-    public void testListMode_ShowsDrop_NoHeader() {
-        createWidget(false);
-        mController.onViewModeChanged(State.MODE_LIST);
-        mDropHeader.assertVisible();
-    }
-
-    @Test
     public void testListMode_ShowsTable() {
         createWidget(true);
         mController.onViewModeChanged(State.MODE_LIST);
-        mDropHeader.assertGone();
         mTableHeader.assertVisible();
     }
 
@@ -64,16 +54,14 @@
         createWidget(true);
         mController.destroy();
 
-        mDropHeader.assertDestroyed();
         mTableHeader.assertDestroyed();
     }
 
     private void createWidget(boolean hasTableHeader) {
-        mDropHeader = new TestWidget();
         if (hasTableHeader) {
             mTableHeader = new TestWidget();
         }
-        mController = new SortController(mDropHeader, mTableHeader);
+        mController = new SortController(mTableHeader);
     }
 
     static class TestWidget implements SortController.WidgetController {
diff --git a/tests/unit/com/android/documentsui/sorting/SortController_TabletLayoutTest.java b/tests/unit/com/android/documentsui/sorting/SortController_TabletLayoutTest.java
index 0423355..171dbc2 100644
--- a/tests/unit/com/android/documentsui/sorting/SortController_TabletLayoutTest.java
+++ b/tests/unit/com/android/documentsui/sorting/SortController_TabletLayoutTest.java
@@ -16,8 +16,8 @@
 
 package com.android.documentsui.sorting;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.base.State;
 import com.android.documentsui.sorting.SortControllerTest.TestWidget;
@@ -34,28 +34,24 @@
 @SmallTest
 public class SortController_TabletLayoutTest {
 
-    private TestWidget mDropHeader;
     private TestWidget mTableHeader;
     private SortController mController;
 
     @Before
     public void setUp() {
-        mDropHeader = new TestWidget();
         mTableHeader = new TestWidget();
-        mController = new SortController(mDropHeader, mTableHeader);
+        mController = new SortController(mTableHeader);
     }
 
     @Test
-    public void testGridMode_ShowsDrop() {
+    public void testGridMode_hidesTable() {
         mController.onViewModeChanged(State.MODE_GRID);
-        mDropHeader.assertVisible();
         mTableHeader.assertGone();
     }
 
     @Test
     public void testListMode_ShowsTable() {
         mController.onViewModeChanged(State.MODE_LIST);
-        mDropHeader.assertGone();
         mTableHeader.assertVisible();
     }
 }
diff --git a/tests/unit/com/android/documentsui/sorting/SortDimensionTest.java b/tests/unit/com/android/documentsui/sorting/SortDimensionTest.java
index c7abb9a..1a6678b 100644
--- a/tests/unit/com/android/documentsui/sorting/SortDimensionTest.java
+++ b/tests/unit/com/android/documentsui/sorting/SortDimensionTest.java
@@ -18,10 +18,11 @@
 
 import static junit.framework.Assert.assertEquals;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.R;
 import com.android.documentsui.sorting.SortDimension.SortCapability;
 import com.android.documentsui.sorting.SortDimension.SortDirection;
diff --git a/tests/unit/com/android/documentsui/sorting/SortModelTest.java b/tests/unit/com/android/documentsui/sorting/SortModelTest.java
index c0acdb6..da89030 100644
--- a/tests/unit/com/android/documentsui/sorting/SortModelTest.java
+++ b/tests/unit/com/android/documentsui/sorting/SortModelTest.java
@@ -20,11 +20,12 @@
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.fail;
 
-import android.support.annotation.Nullable;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
+import androidx.annotation.Nullable;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.documentsui.R;
 import com.android.documentsui.sorting.SortModel.UpdateListener;
 import com.android.documentsui.sorting.SortModel.UpdateType;
diff --git a/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java b/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java
index 6705c4d..e323dc8 100644
--- a/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java
+++ b/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java
@@ -17,6 +17,7 @@
 package com.android.documentsui.sorting;
 
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -26,8 +27,9 @@
 import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.Shared;
diff --git a/tests/unit/com/android/documentsui/theme/ThemeOverlayManagerTest.java b/tests/unit/com/android/documentsui/theme/ThemeOverlayManagerTest.java
new file mode 100644
index 0000000..c87954d
--- /dev/null
+++ b/tests/unit/com/android/documentsui/theme/ThemeOverlayManagerTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2019 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.documentsui.theme;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.os.UserHandle;
+
+import androidx.core.util.Consumer;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.common.collect.Lists;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ThemeOverlayManagerTest {
+    private static final String TEST_DISABLED_PREFIX = "com.example.";
+    private static final String TEST_ENABLED_PREFIX = "com.example.enabled.";
+    private static final String TEST_OVERLAY_PACKAGE = "test.overlay";
+    private static final String TEST_TARGET_PACKAGE = "test.target";
+
+    @Mock
+    OverlayManager mOverlayManager;
+
+    Consumer<Boolean> mCallback;
+    Context mContext;
+    CountDownLatch mLatch;
+    ThemeOverlayManager mThemeOverlayManager;
+    UserHandle mUserHandle;
+
+    @Before
+    public void setUp() throws Exception {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+                "android.permission.CHANGE_OVERLAY_PACKAGES");
+
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        mLatch = new CountDownLatch(1);
+        mUserHandle = UserHandle.of(UserHandle.myUserId());
+        mCallback = result -> mLatch.countDown();
+
+        when(mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(),
+                mUserHandle)).thenReturn(Lists.newArrayList(
+                createOverlayInfo(getOverlayPackageId(), getEnabledTargetPackageId(), true)));
+
+        when(mOverlayManager.getOverlayInfosForTarget(getDisabledTargetPackageId(),
+                mUserHandle)).thenReturn(Lists.newArrayList(
+                createOverlayInfo(getOverlayPackageId(), getDisabledTargetPackageId(), false)));
+    }
+
+    @Test
+    public void testOverlayPackagesForDocumentsUI_shouldBeNonStatic() {
+        final String docsuiPkgId = mContext.getPackageName();
+        final OverlayManager manager = mContext.getSystemService(OverlayManager.class);
+        final List<OverlayInfo> infos = manager.getOverlayInfosForTarget(docsuiPkgId, mUserHandle);
+
+        for (OverlayInfo info : infos) {
+            assertThat(info.isStatic).isFalse();
+        }
+    }
+
+    @Test
+    public void testApplyOverlays_shouldSetEnabled() throws Exception {
+        final boolean enabled = true;
+
+        mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager,
+                getDisabledTargetPackageId());
+
+        mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback);
+        mLatch.await(5, TimeUnit.SECONDS);
+
+        verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled,
+                mUserHandle);
+    }
+
+    @Test
+    public void testApplyOverlays_shouldGetOverlayInfo() throws Exception {
+        mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager,
+                getEnabledTargetPackageId());
+
+        mThemeOverlayManager.applyOverlays(mContext, true /* enabled */, mCallback);
+        mLatch.await(5, TimeUnit.SECONDS);
+
+        verify(mOverlayManager, times(1)).getOverlayInfosForTarget(getEnabledTargetPackageId(),
+                mUserHandle);
+    }
+
+    @Test
+    public void testApplyOverlays_shouldCheckEnabled_beforeSetEnabled() {
+        final boolean enabled = true;
+
+        mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager,
+                getEnabledTargetPackageId());
+
+        mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback);
+
+        verify(mOverlayManager, never()).setEnabled(getOverlayPackageId(), enabled,
+                mUserHandle);
+    }
+
+    @Test
+    public void testDefaultDisabled_applyOverlays_shouldEnabled() throws Exception {
+        final boolean enabled = true;
+
+        assertThat(mOverlayManager.getOverlayInfosForTarget(getDisabledTargetPackageId(),
+                mUserHandle).get(0).isEnabled()).isEqualTo(!enabled);
+
+        mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager,
+                getDisabledTargetPackageId());
+
+        mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback);
+        mLatch.await(5, TimeUnit.SECONDS);
+
+        verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled,
+                mUserHandle);
+    }
+
+    @Test
+    public void testDefaultEnabled_applyOverlays_shouldDisabled() throws Exception {
+        final boolean enabled = false;
+
+        assertThat(mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(),
+                mUserHandle).get(0).isEnabled()).isEqualTo(!enabled);
+
+        mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager,
+                getEnabledTargetPackageId());
+
+        mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback);
+        mLatch.await(5, TimeUnit.SECONDS);
+
+        verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled,
+                mUserHandle);
+    }
+
+    @Test
+    public void testDefaultEnabled_launchDocumentsUI_shouldSuccess() throws Exception {
+        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        final Activity activity =
+                InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
+
+        assertThat(activity).isNotNull();
+
+        if (activity != null) {
+            activity.finish();
+        }
+    }
+
+    private static OverlayInfo createOverlayInfo(String packageName, String targetPackageName,
+            boolean enabled) {
+        return new OverlayInfo(packageName, targetPackageName, null, null, "",
+                enabled ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED, 0, 0, false);
+    }
+
+    private static String getDisabledTargetPackageId() {
+        return TEST_DISABLED_PREFIX + TEST_TARGET_PACKAGE;
+    }
+
+    private static String getEnabledTargetPackageId() {
+        return TEST_ENABLED_PREFIX + TEST_TARGET_PACKAGE;
+    }
+
+    private static String getOverlayPackageId() {
+        return TEST_DISABLED_PREFIX + TEST_OVERLAY_PACKAGE;
+    }
+
+}
diff --git a/tests/unit/com/android/documentsui/ui/DarkThemeUiTest.java b/tests/unit/com/android/documentsui/ui/DarkThemeUiTest.java
new file mode 100644
index 0000000..33938a2
--- /dev/null
+++ b/tests/unit/com/android/documentsui/ui/DarkThemeUiTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 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.documentsui.ui;
+
+import android.content.Context;
+import android.content.res.Configuration;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.tests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * This class test default Dark Theme (Night Mode Disable)
+ * Verify ActionBar background, Window background, and GridItem background to meet Light style
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DarkThemeUiTest extends ThemeUiTestBase {
+    Context mTestContext;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mTestContext = InstrumentationRegistry.getContext();
+        mTheme = getThemeByUiMode(mTargetContext, Configuration.UI_MODE_NIGHT_YES);
+    }
+
+    @Test
+    public void themeNightModeEnable_actionBarColorShouldBeDark() {
+        assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorBackground,
+                mTheme.getResources().getColor(com.android.documentsui.R.color.app_background_color,
+                        mTheme));
+    }
+
+    @Test
+    public void themeNightModeEnable_windowLightNavigationBarShouldBeFalse() {
+        assertTheme(R.styleable.SystemWindow,
+                R.styleable.SystemWindow_android_windowLightNavigationBar, false);
+    }
+
+    @Test
+    public void themeNightModeEnable_windowLightStatusBarShouldBeFalse() {
+        assertTheme(R.styleable.SystemWindow,
+                R.styleable.SystemWindow_android_windowLightNavigationBar, false);
+    }
+
+    @Test
+    public void themeNightModeEnable_navigationBarColorShouldBeDark() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_navigationBarColor,
+                mTheme.getResources().getColor(android.R.color.black, mTheme));
+    }
+
+    @Test
+    public void themeNightModeEnable_windowBackgroundColorShouldBeDark() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_windowBackground,
+                mTheme.getResources().getColor(com.android.documentsui.R.color.app_background_color,
+                        mTheme));
+    }
+
+    @Test
+    public void themeNightModeEnable_statusBarColorShouldBeDark() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_statusBarColor,
+                mTheme.getResources().getColor(com.android.documentsui.R.color.app_background_color,
+                        mTheme));
+    }
+
+    @Test
+    public void appCompatThemeNightModeEnable_colorPrimaryShouldBeThemeable() {
+        assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorPrimary,
+                mTheme.getResources().getColor(com.android.documentsui.R.color.primary, mTheme));
+    }
+}
\ No newline at end of file
diff --git a/tests/unit/com/android/documentsui/ui/SearchBarScrollingViewBehaviorTest.java b/tests/unit/com/android/documentsui/ui/SearchBarScrollingViewBehaviorTest.java
new file mode 100644
index 0000000..bab82dd
--- /dev/null
+++ b/tests/unit/com/android/documentsui/ui/SearchBarScrollingViewBehaviorTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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.documentsui.ui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import androidx.test.InstrumentationRegistry;
+
+import com.android.documentsui.R;
+
+import com.google.android.material.appbar.AppBarLayout;
+
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class SearchBarScrollingViewBehaviorTest {
+    private SearchBarScrollingViewBehavior mScrollingViewBehavior;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        mScrollingViewBehavior = new SearchBarScrollingViewBehavior(mContext, null);
+    }
+
+    @Test
+    public void shouldHeaderOverlapScrollingChild_returnTrue() {
+        assertTrue(mScrollingViewBehavior.shouldHeaderOverlapScrollingChild());
+    }
+
+    @Test
+    public void setAppBarLayoutTransparent_defaultWhiteBackground_shouldBeTransparent() {
+        mContext.setTheme(R.style.DocumentsTheme);
+        mContext.getTheme().applyStyle(R.style.DocumentsDefaultTheme, false);
+        final CoordinatorLayout coordinatorLayout = new CoordinatorLayout(mContext);
+        final AppBarLayout appBarLayout = new AppBarLayout(mContext);
+        final CoordinatorLayout.LayoutParams lp = mock(CoordinatorLayout.LayoutParams.class);
+        lp.setBehavior(mScrollingViewBehavior);
+        appBarLayout.setLayoutParams(lp);
+        appBarLayout.setBackgroundColor(Color.WHITE);
+        mScrollingViewBehavior.onDependentViewChanged(coordinatorLayout, null, appBarLayout);
+
+        assertEquals(Color.TRANSPARENT, ((ColorDrawable) appBarLayout.getBackground()).getColor());
+    }
+}
diff --git a/tests/unit/com/android/documentsui/ui/ThemeUiTest.java b/tests/unit/com/android/documentsui/ui/ThemeUiTest.java
new file mode 100644
index 0000000..292ea83
--- /dev/null
+++ b/tests/unit/com/android/documentsui/ui/ThemeUiTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.documentsui.ui;
+
+import android.content.res.Configuration;
+import android.graphics.Color;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.tests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * This class test default Light Theme (Night Mode Disable)
+ * Verify ActionBar background, Window background, and GridItem background to meet Light style
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ThemeUiTest extends ThemeUiTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mTheme = getThemeByUiMode(mTargetContext, Configuration.UI_MODE_NIGHT_NO);
+    }
+
+    @Test
+    public void themeNightModeDisable_actionBarColorShouldBeLight() {
+        assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorBackground,
+                Color.WHITE);
+    }
+
+    @Test
+    public void themeNightModeDisable_windowLightNavigationBarShouldBeTrue() {
+        assertTheme(R.styleable.SystemWindow,
+                R.styleable.SystemWindow_android_windowLightNavigationBar, true);
+    }
+
+    @Test
+    public void themeNightModeDisable_windowLightStatusBarShouldBeTrue() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_windowLightStatusBar,
+                true);
+    }
+
+    @Test
+    public void themeNightModeDisable_navigationBarColorShouldBeLight() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_navigationBarColor,
+                Color.WHITE);
+    }
+
+    @Test
+    public void themeNightModeDisable_windowBackgroundColorShouldBeLight() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_windowBackground,
+                Color.WHITE);
+    }
+
+    @Test
+    public void themeNightModeDisable_statusBarColorShouldBeLight() {
+        assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_statusBarColor,
+                Color.WHITE);
+    }
+
+    @Test
+    public void appCompatThemeNightModeDisable_colorPrimaryShouldBeThemeable() {
+        assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorPrimary,
+                mTheme.getResources().getColor(com.android.documentsui.R.color.primary, mTheme));
+    }
+}
diff --git a/tests/unit/com/android/documentsui/ui/ThemeUiTestBase.java b/tests/unit/com/android/documentsui/ui/ThemeUiTestBase.java
new file mode 100644
index 0000000..b6f4217
--- /dev/null
+++ b/tests/unit/com/android/documentsui/ui/ThemeUiTestBase.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 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.documentsui.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.util.DisplayMetrics;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+/**
+ * The TestBase class define getThemeByUiMode API and prepare setUp and tearDown for Theme test
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public abstract class ThemeUiTestBase {
+    protected Context mTargetContext;
+    protected Configuration mConfiguration;
+    protected DisplayMetrics mDisplayMetrics;
+    protected CompatibilityInfo mCompatibilityInfo;
+    protected Resources.Theme mTheme;
+
+    @Before
+    public void setUp() throws Exception {
+        mTargetContext = InstrumentationRegistry.getTargetContext();
+        mConfiguration = mTargetContext.getResources().getConfiguration();
+        mDisplayMetrics = mTargetContext.getResources().getDisplayMetrics();
+        mCompatibilityInfo = mTargetContext.getResources().getCompatibilityInfo();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTargetContext.getResources().updateConfiguration(mConfiguration, mDisplayMetrics,
+                mCompatibilityInfo);
+    }
+
+    /**
+     * The method to return the customized theme base on UI_MODE_NIGHT_YES or UI_MODE_NIGHT_NO
+     *
+     * @param context       The applicationContext from Test App
+     * @param nightModeFlag Only support Configuration.UI_MODE_NIGHT_YES or UI_MODE_NIGHT_NO
+     * @return Resources.Theme Applied target App's style/DocumentsTheme
+     */
+    protected Resources.Theme getThemeByUiMode(Context context, int nightModeFlag) {
+        final CompatibilityInfo ci = context.getResources().getCompatibilityInfo();
+        final DisplayMetrics dm = context.getResources().getDisplayMetrics();
+        final Configuration nightConfig = new Configuration(
+                context.getResources().getConfiguration());
+        nightConfig.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
+        nightConfig.uiMode |= nightModeFlag;
+        context.getResources().updateConfiguration(nightConfig, dm, ci);
+        // Resources.theme won't be updated by updateConfiguration()
+        // hence, we need to create new Resources.theme to force apply again
+        final Resources.Theme theme = context.getResources().newTheme();
+        theme.applyStyle(R.style.DocumentsTheme, true);
+        theme.applyStyle(R.style.DocumentsDefaultTheme, false);
+        return theme;
+    }
+
+    /**
+     * The method to assert target theme defined color match expected color
+     *
+     * @param styleable The scope of attrs defined in the theme
+     * @param attr      The specific target color to retrieve
+     * @param expected  The expected color in the theme
+     */
+    protected void assertTheme(int[] styleable, int attr, int expected) {
+        final TypedArray ta = mTheme.obtainStyledAttributes(styleable);
+        final int targetColor = ta.getColor(attr, ~expected);
+        ta.recycle();
+        assertThat(targetColor).isEqualTo(expected);
+    }
+
+    /**
+     * The method to assert target theme defined config match expected boolean
+     *
+     * @param styleable The scope of attrs defined in the theme
+     * @param attr      The specific target config to retrieve
+     * @param expected  The expected boolean of defined attr in the theme
+     */
+    protected void assertTheme(int[] styleable, int attr, boolean expected) {
+        final TypedArray ta = mTheme.obtainStyledAttributes(styleable);
+        final boolean targetBoolean = ta.getBoolean(attr, !expected);
+        ta.recycle();
+        assertThat(targetBoolean).isEqualTo(expected);
+    }
+}
diff --git a/tests/unit/com/android/documentsui/util/FormatUtilsTest.java b/tests/unit/com/android/documentsui/util/FormatUtilsTest.java
new file mode 100644
index 0000000..3f8127b
--- /dev/null
+++ b/tests/unit/com/android/documentsui/util/FormatUtilsTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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.documentsui.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class FormatUtilsTest {
+    @Test
+    public void testFormatDuration_seconds() {
+        assertEquals("0 seconds", FormatUtils.formatDuration(0));
+        assertEquals("0 seconds", FormatUtils.formatDuration(1));
+        assertEquals("0 seconds", FormatUtils.formatDuration(499));
+        assertEquals("1 second", FormatUtils.formatDuration(500));
+        assertEquals("1 second", FormatUtils.formatDuration(1000));
+        assertEquals("2 seconds", FormatUtils.formatDuration(1500));
+    }
+
+    @Test
+    public void testFormatDuration_Minutes() {
+        assertEquals("59 seconds", FormatUtils.formatDuration(59000));
+        assertEquals("60 seconds", FormatUtils.formatDuration(59500));
+        assertEquals("1 minute", FormatUtils.formatDuration(60000));
+        assertEquals("1 minute", FormatUtils.formatDuration(65000));
+        assertEquals("2 minutes", FormatUtils.formatDuration(90000));
+        assertEquals("2 minutes", FormatUtils.formatDuration(120000));
+    }
+
+    @Test
+    public void testFormatDuration_Hours() {
+        assertEquals("59 minutes", FormatUtils.formatDuration(3540000));
+        assertEquals("1 hour", FormatUtils.formatDuration(3600000));
+        assertEquals("1 hour", FormatUtils.formatDuration(3660000));
+        assertEquals("2 hours", FormatUtils.formatDuration(5400000));
+        assertEquals("48 hours", FormatUtils.formatDuration(172800000));
+    }
+
+}