Merge "Don't use std::stoi()" into mainline-prod am: 671e241bf2

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/providers/MediaProvider/+/13007436

Change-Id: Icda0e6bacec1b3f51fc632959d8e6e1c1ba39f97
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 305027b..e937ef3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -52,7 +52,8 @@
         </provider>
 
         <!-- Handles database upgrades after OTAs, then disables itself -->
-        <receiver android:name="com.android.providers.media.MediaUpgradeReceiver">
+        <receiver android:name="com.android.providers.media.MediaUpgradeReceiver"
+            android:exported="true">
             <!-- This broadcast is sent after the core system has finished
                  booting, before the home app is launched or BOOT_COMPLETED
                  is sent. -->
@@ -61,7 +62,8 @@
             </intent-filter>
         </receiver>
 
-        <receiver android:name="com.android.providers.media.MediaReceiver">
+        <receiver android:name="com.android.providers.media.MediaReceiver"
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
             </intent-filter>
@@ -94,6 +96,7 @@
             android:permission="android.permission.BIND_JOB_SERVICE" />
 
         <service android:name="com.android.providers.media.fuse.ExternalStorageServiceImpl"
+                 android:exported="true"
                  android:permission="android.permission.BIND_EXTERNAL_STORAGE_SERVICE">
             <intent-filter>
                 <action android:name="android.service.storage.ExternalStorageService" />
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/OWNERS b/OWNERS
index 4e37503..a1580ff 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,4 +4,4 @@
 nandana@google.com
 zezeozue@google.com
 corinac@google.com
-sahanas@google.com
\ No newline at end of file
+sahanas@google.com
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
index 6d8da53..ffef8fb 100644
--- a/apex/apex_manifest.json
+++ b/apex/apex_manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.mediaprovider",
-  "version": 309999900
+  "version": 300000000
 }
diff --git a/apex/framework/api/current.txt b/apex/framework/api/current.txt
index 52439fb..646e1ac 100644
--- a/apex/framework/api/current.txt
+++ b/apex/framework/api/current.txt
@@ -26,6 +26,7 @@
     field public static final String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
     field public static final String AUTHORITY = "media";
     field @NonNull public static final android.net.Uri AUTHORITY_URI;
+    field public static final String EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT = "android.provider.extra.ACCEPT_ORIGINAL_MEDIA_FORMAT";
     field public static final String EXTRA_BRIGHTNESS = "android.provider.extra.BRIGHTNESS";
     field public static final String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";
     field public static final String EXTRA_FINISH_ON_COMPLETION = "android.intent.extra.finishOnCompletion";
@@ -114,7 +115,7 @@
     field public static final android.net.Uri INTERNAL_CONTENT_URI;
   }
 
-  public static final class MediaStore.Audio.Artists.Albums implements android.provider.MediaStore.Audio.AlbumColumns {
+  public static final class MediaStore.Audio.Artists.Albums implements android.provider.BaseColumns android.provider.MediaStore.Audio.AlbumColumns {
     ctor public MediaStore.Audio.Artists.Albums();
     method public static android.net.Uri getContentUri(String, long);
   }
diff --git a/apex/framework/java/android/provider/MediaStore.java b/apex/framework/java/android/provider/MediaStore.java
index 73f56ef..7ecabdb 100644
--- a/apex/framework/java/android/provider/MediaStore.java
+++ b/apex/framework/java/android/provider/MediaStore.java
@@ -48,6 +48,7 @@
 import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.Environment;
@@ -585,6 +586,26 @@
      */
     public final static String EXTRA_OUTPUT = "output";
 
+    // TODO(b/158465539): Add API to explicitly specify media capabilities via Bundle
+    /**
+     * Specify that the caller wants to receive the original media format without transcoding.
+     *
+     * This is a very dangerous flag to use because apps can suddenly fail to play media after
+     * an OS upgrade. Clients should instead specify their supported media capabilities explicitly
+     * in their manifest.
+     *
+     * This is useful for apps that usually receive transcoded media, but want to have more granular
+     * control.
+     *
+     * <p>This option can be added to the {@code opts} {@link Bundle} in various
+     * {@link ContentResolver} {@code open} methods.
+     *
+     * @see ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)
+     * @see ContentResolver#openTypedAssetFile(Uri, String, Bundle, CancellationSignal)
+     */
+    public final static String EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT =
+            "android.provider.extra.ACCEPT_ORIGINAL_MEDIA_FORMAT";
+
     /**
       * The string that is used when a media attribute is not known. For example,
       * if an audio file does not have any meta data, the artist and album columns
@@ -1596,7 +1617,7 @@
              * The MTP storage ID of the file
              * @hide
              */
-            @UnsupportedAppUsage
+            @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
             @Deprecated
             // @Column(Cursor.FIELD_TYPE_INTEGER)
             public static final String STORAGE_ID = "storage_id";
@@ -1684,6 +1705,41 @@
              * Constant for the {@link #MEDIA_TYPE} column indicating that file is a document file.
              */
             public static final int MEDIA_TYPE_DOCUMENT = 6;
+
+            /**
+             * Status of the transcode file
+             *
+             * For apps that do not support modern media formats for video, we
+             * seamlessly transcode the file and return transcoded file for
+             * both file path and ContentResolver operations. This column tracks
+             * the status of the transcoded file.
+             *
+             * @hide
+             */
+            @Column(value = Cursor.FIELD_TYPE_INTEGER)
+            public static final String _TRANSCODE_STATUS = "_transcode_status";
+
+            /**
+             * Constant for the {@link #_TRANSCODE_STATUS} column indicating
+             * that the transcode file if exists is empty or never transcoded.
+             * @hide
+             */
+            public static final int TRANSCODE_EMPTY = 0;
+
+            /**
+             * Constant for the {@link #_TRANSCODE_STATUS} column indicating
+             * that the transcode file if exists contains transcoded video.
+             * @hide
+             */
+            public static final int TRANSCODE_COMPLETE = 1;
+
+            /**
+             * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_CODEC_TYPE}
+             * extracted from the video file. This value be null for non-video files.
+             * @hide
+             */
+            @Column(value = Cursor.FIELD_TYPE_INTEGER)
+            public static final String _VIDEO_CODEC_TYPE = "_video_codec_type";
         }
     }
 
@@ -3073,7 +3129,7 @@
              * Sub-directory of each artist containing all albums on which
              * a song by the artist appears.
              */
-            public static final class Albums implements AlbumColumns {
+            public static final class Albums implements BaseColumns, AlbumColumns {
                 public static final Uri getContentUri(String volumeName,long artistId) {
                     return ContentUris
                             .withAppendedId(Audio.Artists.getContentUri(volumeName), artistId)
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index 317c081..7d1a7cd 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -14,11 +14,14 @@
 
     static_libs: [
         "//external/error_prone:error_prone_core",
-        "//external/dagger2:dagger2-auto-service",
+    ],
+
+    libs: [
+        "//external/auto:auto_service_annotations",
     ],
 
     plugins: [
-        "//external/dagger2:dagger2-auto-service",
+        "//external/auto:auto_service_plugin",
     ],
 
     javacflags: ["-verbose"],
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index b6deb60..d0785bd 100644
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -110,8 +110,8 @@
 
 // Regex copied from FileUtils.java in MediaProvider, but without media directory.
 const std::regex PATTERN_OWNED_PATH(
-    "^/storage/[^/]+/(?:[0-9]+/)?Android/(?:data|obb|sandbox)/([^/]+)(/?.*)?",
-    std::regex_constants::icase);
+        "^/storage/[^/]+/(?:[0-9]+/)?Android/(?:data|obb)/([^/]+)(/?.*)?",
+        std::regex_constants::icase);
 
 /*
  * In order to avoid double caching with fuse, call fadvise on the file handles
@@ -388,14 +388,12 @@
     }
 }
 
-static double get_timeout(struct fuse* fuse, const string& path, bool should_inval) {
-    string media_path = fuse->GetEffectiveRootPath() + "/Android/media";
-    if (fuse->disable_dentry_cache || should_inval || path.find(media_path, 0) == 0 || is_package_owned_path(path, fuse->path)) {
+static double get_attr_timeout(const string& path, bool should_inval, node* node,
+                               struct fuse* fuse) {
+    if (fuse->disable_dentry_cache || should_inval || is_package_owned_path(path, fuse->path)) {
         // We set dentry timeout to 0 for the following reasons:
-        // 1. Case-insensitive lookups need to invalidate other case-insensitive dentry matches
-        // 2. Installd might delete Android/media/<package> dirs when app data is cleared.
-        // This can leave a stale entry in the kernel dcache, and break subsequent creation of the
-        // dir via FUSE.
+        // 1. The dentry cache was completely disabled
+        // 2. Case-insensitive lookups need to invalidate other case-insensitive dentry matches
         // 3. With app data isolation enabled, app A should not guess existence of app B from the
         // Android/{data,obb}/<package> paths, hence we prevent the kernel from caching that
         // information.
@@ -404,6 +402,23 @@
     return std::numeric_limits<double>::max();
 }
 
+static double get_entry_timeout(const string& path, bool should_inval, node* node,
+                                struct fuse* fuse) {
+    string media_path = fuse->GetEffectiveRootPath() + "/Android/media";
+    if (path.find(media_path, 0) == 0) {
+        // Installd might delete Android/media/<package> dirs when app data is cleared.
+        // This can leave a stale entry in the kernel dcache, and break subsequent creation of the
+        // dir via FUSE.
+        return 0;
+    }
+    return get_attr_timeout(path, should_inval, node, fuse);
+}
+
+static std::string get_path(node* node) {
+    const string& io_path = node->GetIoPath();
+    return io_path.empty() ? node->BuildPath() : io_path;
+}
+
 static node* make_node_entry(fuse_req_t req, node* parent, const string& name, const string& path,
                              struct fuse_entry_param* e, int* error_code) {
     struct fuse* fuse = get_fuse(req);
@@ -417,11 +432,49 @@
     }
 
     bool should_inval = false;
-    node = parent->LookupChildByName(name, true /* acquire */);
+    bool transforms_complete = true;
+    int transforms = 0;
+    string io_path;
+
+    if (S_ISREG(e->attr.st_mode)) {
+        // Handle potential file transforms
+        transforms = fuse->mp->GetTransforms(path, req->ctx.uid);
+
+        if (transforms < 0) {
+            // Fail lookup if we can't fetch supported transforms for path
+            LOG(WARNING) << "Failed to fetch transforms for " << name;
+            *error_code = ENOENT;
+            return NULL;
+        }
+
+        // TODO(b/169412244): Improve JNI interaction
+        // Invalidate if there are any transforms so that we always get a lookup into userspace
+        should_inval = should_inval || transforms;
+        if (transforms) {
+            // If there are any transforms, fetch IO path
+            io_path = fuse->mp->GetIoPath(path, req->ctx.uid);
+            if (io_path.empty()) {
+                *error_code = EFAULT;
+                return NULL;
+            }
+
+            if (io_path != path) {
+                // Update size with io_path size
+                if (lstat(io_path.c_str(), &e->attr) < 0) {
+                    *error_code = errno;
+                    return NULL;
+                }
+                transforms_complete = false;
+            }
+        }
+    }
+
+    node = parent->LookupChildByName(name, true /* acquire */, transforms);
     if (!node) {
-        node = ::node::Create(parent, name, &fuse->lock, &fuse->tracker);
+        node = ::node::Create(parent, name, io_path, transforms_complete, transforms, &fuse->lock,
+                              &fuse->tracker);
     } else if (!mediaprovider::fuse::containsMount(path, std::to_string(getuid() / PER_USER_RANGE))) {
-        should_inval = node->HasCaseInsensitiveMatch();
+        should_inval = should_inval || node->HasCaseInsensitiveMatch();
         // Only invalidate a path if it does not contain mount.
         // Invalidate both names to ensure there's no dentry left in the kernel after the following
         // operations:
@@ -455,11 +508,8 @@
     // reuse inode numbers.
     e->generation = 0;
     e->ino = fuse->ToInode(node);
-    e->entry_timeout = get_timeout(fuse, path, should_inval);
-    e->attr_timeout = is_package_owned_path(path, fuse->path) || should_inval
-                              ? 0
-                              : std::numeric_limits<double>::max();
-
+    e->entry_timeout = get_entry_timeout(path, should_inval, node, fuse);
+    e->attr_timeout = get_attr_timeout(path, should_inval, node, fuse);
     return node;
 }
 
@@ -619,7 +669,7 @@
         fuse_reply_err(req, ENOENT);
         return;
     }
-    string path = node->BuildPath();
+    const string& path = get_path(node);
     if (!is_app_accessible_path(fuse->mp, path, req->ctx.uid)) {
         fuse_reply_err(req, ENOENT);
         return;
@@ -631,8 +681,10 @@
     if (lstat(path.c_str(), &s) < 0) {
         fuse_reply_err(req, errno);
     } else {
-        fuse_reply_attr(req, &s, is_package_owned_path(path, fuse->path) ?
-                0 : std::numeric_limits<double>::max());
+        fuse_reply_attr(
+                req, &s,
+                get_attr_timeout(path, node->GetTransforms() || node->HasCaseInsensitiveMatch(),
+                                 node, fuse));
     }
 }
 
@@ -648,7 +700,7 @@
         fuse_reply_err(req, ENOENT);
         return;
     }
-    string path = node->BuildPath();
+    const string& path = get_path(node);
     if (!is_app_accessible_path(fuse->mp, path, req->ctx.uid)) {
         fuse_reply_err(req, ENOENT);
         return;
@@ -727,15 +779,16 @@
     }
 
     lstat(path.c_str(), attr);
-    fuse_reply_attr(req, attr, is_package_owned_path(path, fuse->path) ?
-            0 : std::numeric_limits<double>::max());
+    fuse_reply_attr(req, attr,
+                    get_attr_timeout(path, node->GetTransforms() || node->HasCaseInsensitiveMatch(),
+                                     node, fuse));
 }
 
 static void pf_canonical_path(fuse_req_t req, fuse_ino_t ino)
 {
     struct fuse* fuse = get_fuse(req);
     node* node = fuse->FromInode(ino);
-    string path = node ? node->BuildPath() : "";
+    const string& path = node ? get_path(node) : "";
 
     if (node && is_app_accessible_path(fuse->mp, path, req->ctx.uid)) {
         // TODO(b/147482155): Check that uid has access to |path| and its contents
@@ -852,12 +905,8 @@
         return;
     }
 
-    node* child_node = parent_node->LookupChildByName(name, false /* acquire */);
-    TRACE_NODE(child_node, req);
-    if (child_node) {
-        child_node->SetDeleted();
-    }
-
+    // TODO(b/169306422): Log each deleted node
+    parent_node->SetDeletedForChild(name);
     fuse_reply_err(req, 0);
 }
 
@@ -938,10 +987,7 @@
     TRACE_NODE(old_parent_node, req);
     TRACE_NODE(new_parent_node, req);
 
-    node* child_node = old_parent_node->LookupChildByName(name, true /* acquire */);
-    TRACE_NODE(child_node, req) << "old_child";
-
-    const string old_child_path = child_node->BuildPath();
+    const string old_child_path = old_parent_path + "/" + name;
     const string new_child_path = new_parent_path + "/" + new_name;
 
     // TODO(b/147408834): Check ENOTEMPTY & EEXIST error conditions before JNI call.
@@ -949,11 +995,9 @@
     // TODO(b/145663158): Lookups can go out of sync if file/directory is actually moved but
     // EFAULT/EIO is reported due to JNI exception.
     if (res == 0) {
-        child_node->Rename(new_name, new_parent_node);
+        // TODO(b/169306422): Log each renamed node
+        old_parent_node->RenameChild(name, new_name, new_parent_node);
     }
-    TRACE_NODE(child_node, req) << "new_child";
-
-    child_node->Release(1);
     return res;
 }
 
@@ -971,8 +1015,8 @@
 }
 */
 
-static handle* create_handle_for_node(struct fuse* fuse, const string& path, int fd, node* node,
-                                      const RedactionInfo* ri, int* keep_cache) {
+static handle* create_handle_for_node(struct fuse* fuse, const string& path, int fd, uid_t uid,
+                                      node* node, const RedactionInfo* ri, int* keep_cache) {
     std::lock_guard<std::recursive_mutex> guard(fuse->lock);
     // We don't want to use the FUSE VFS cache in two cases:
     // 1. When redaction is needed because app A with EXIF access might access
@@ -1002,7 +1046,7 @@
     }
 
     bool direct_io = (is_cached_file_open && is_redaction_change) || is_file_locked(fd, path);
-    handle* h = new handle(fd, ri, !direct_io);
+    handle* h = new handle(fd, ri, !direct_io, uid);
     node->AddHandle(h);
     return h;
 }
@@ -1016,7 +1060,8 @@
         return;
     }
     const struct fuse_ctx* ctx = fuse_req_ctx(req);
-    const string path = node->BuildPath();
+    const string& path = get_path(node);
+    const string& build_path = node->BuildPath();
     if (!is_app_accessible_path(fuse->mp, path, ctx->uid)) {
         fuse_reply_err(req, ENOENT);
         return;
@@ -1029,7 +1074,10 @@
         fi->direct_io = true;
     }
 
-    int status = fuse->mp->IsOpenAllowed(path, ctx->uid, is_requesting_write(fi->flags));
+    // TODO: If transform, disallow write
+    // Force permission check with the build path because the MediaProvider database might not be
+    // aware of the io_path
+    int status = fuse->mp->IsOpenAllowed(build_path, ctx->uid, is_requesting_write(fi->flags));
     if (status) {
         fuse_reply_err(req, status);
         return;
@@ -1058,6 +1106,8 @@
     if (is_requesting_write(fi->flags)) {
         ri = std::make_unique<RedactionInfo>();
     } else {
+        // TODO(b/171953356): Pass build_path for use during query, otherwise, MediaProvider would
+        // find the transcoded path
         ri = fuse->mp->GetRedactionInfo(path, req->ctx.uid, req->ctx.pid);
     }
 
@@ -1068,7 +1118,8 @@
     }
 
     int keep_cache = 1;
-    handle* h = create_handle_for_node(fuse, path, fd, node, ri.release(), &keep_cache);
+    handle* h =
+            create_handle_for_node(fuse, path, fd, req->ctx.uid, node, ri.release(), &keep_cache);
     fi->fh = ptr_to_id(h);
     fi->keep_cache = keep_cache;
     fi->direct_io = !h->cached;
@@ -1153,6 +1204,17 @@
     handle* h = reinterpret_cast<handle*>(fi->fh);
     struct fuse* fuse = get_fuse(req);
 
+    node* node = fuse->FromInode(ino);
+
+    if (!node->IsTransformsComplete()) {
+        if (!fuse->mp->Transform(node->BuildPath(), node->GetIoPath(), node->GetTransforms(),
+                                 h->uid)) {
+            fuse_reply_err(req, EFAULT);
+            return;
+        }
+        node->SetTransformsComplete();
+    }
+
     fuse->fadviser.Record(h->fd, size);
 
     if (h->ri->isRedactionNeeded()) {
@@ -1224,14 +1286,6 @@
     fuse_reply_write(req, size);
 }
 #endif
-static void pf_flush(fuse_req_t req,
-                     fuse_ino_t ino,
-                     struct fuse_file_info* fi) {
-    ATRACE_CALL();
-    struct fuse* fuse = get_fuse(req);
-    TRACE_NODE(nullptr, req) << "noop";
-    fuse_reply_err(req, 0);
-}
 
 static void pf_release(fuse_req_t req,
                        fuse_ino_t ino,
@@ -1602,7 +1656,8 @@
     // to the file before all the EXIF content is written. We could special case reads before the
     // first close after a file has just been created.
     int keep_cache = 1;
-    handle* h = create_handle_for_node(fuse, child_path, fd, node, new RedactionInfo(), &keep_cache);
+    handle* h = create_handle_for_node(fuse, child_path, fd, req->ctx.uid, node,
+                                       new RedactionInfo(), &keep_cache);
     fi->fh = ptr_to_id(h);
     fi->keep_cache = keep_cache;
     fi->direct_io = !h->cached;
@@ -1669,7 +1724,7 @@
     /*.link = pf_link,*/
     .open = pf_open, .read = pf_read,
     /*.write = pf_write,*/
-    .flush = pf_flush,
+    /*.flush = pf_flush,*/
     .release = pf_release, .fsync = pf_fsync, .opendir = pf_opendir, .readdir = pf_readdir,
     .releasedir = pf_releasedir, .fsyncdir = pf_fsyncdir, .statfs = pf_statfs,
     /*.setxattr = pf_setxattr,
diff --git a/jni/MediaProviderWrapper.cpp b/jni/MediaProviderWrapper.cpp
index b0db1ca..167fb6f 100644
--- a/jni/MediaProviderWrapper.cpp
+++ b/jni/MediaProviderWrapper.cpp
@@ -285,6 +285,12 @@
                                            /*is_static*/ false);
     mid_is_app_clone_user_ = CacheMethod(env, "isAppCloneUser", "(I)Z",
                                          /*is_static*/ false);
+    mid_get_io_path_ = CacheMethod(env, "getIoPath", "(Ljava/lang/String;I)Ljava/lang/String;",
+                                   /*is_static*/ false);
+    mid_get_transforms_ = CacheMethod(env, "getTransforms", "(Ljava/lang/String;I)I",
+                                      /*is_static*/ false);
+    mid_transform_ = CacheMethod(env, "transform", "(Ljava/lang/String;Ljava/lang/String;II)Z",
+                                 /*is_static*/ false);
 }
 
 MediaProviderWrapper::~MediaProviderWrapper() {
@@ -451,6 +457,50 @@
     return res;
 }
 
+std::string MediaProviderWrapper::GetIoPath(const std::string& path, uid_t uid) {
+    JNIEnv* env = MaybeAttachCurrentThread();
+
+    ScopedLocalRef<jstring> j_path(env, env->NewStringUTF(path.c_str()));
+    ScopedLocalRef<jstring> j_res_path(
+            env, static_cast<jstring>(env->CallObjectMethod(media_provider_object_,
+                                                            mid_get_io_path_, j_path.get(), uid)));
+    ScopedUtfChars j_res_utf(env, j_res_path.get());
+    if (CheckForJniException(env)) {
+        return "";
+    }
+
+    return string(j_res_utf.c_str());
+}
+
+int MediaProviderWrapper::GetTransforms(const std::string& path, uid_t uid) {
+    JNIEnv* env = MaybeAttachCurrentThread();
+
+    ScopedLocalRef<jstring> j_path(env, env->NewStringUTF(path.c_str()));
+    int res = env->CallIntMethod(media_provider_object_, mid_get_transforms_, j_path.get(), uid);
+
+    if (CheckForJniException(env)) {
+        return -1;
+    }
+
+    return res;
+}
+
+bool MediaProviderWrapper::Transform(const std::string& src, const std::string& dst, int transforms,
+                                     uid_t uid) {
+    JNIEnv* env = MaybeAttachCurrentThread();
+
+    ScopedLocalRef<jstring> j_src(env, env->NewStringUTF(src.c_str()));
+    ScopedLocalRef<jstring> j_dst(env, env->NewStringUTF(dst.c_str()));
+    bool res = env->CallBooleanMethod(media_provider_object_, mid_transform_, j_src.get(),
+                                      j_dst.get(), transforms, uid);
+
+    if (CheckForJniException(env)) {
+        return false;
+    }
+
+    return res;
+}
+
 /*****************************************************************************************/
 /******************************** Private member functions *******************************/
 /*****************************************************************************************/
diff --git a/jni/MediaProviderWrapper.h b/jni/MediaProviderWrapper.h
index 4e931e8..b5060a3 100644
--- a/jni/MediaProviderWrapper.h
+++ b/jni/MediaProviderWrapper.h
@@ -165,6 +165,15 @@
      */
     void OnFileCreated(const std::string& path);
 
+    /** Get path for actual I/O */
+    std::string GetIoPath(const std::string& path, uid_t uid);
+
+    /** Get supported transformations for path and transform actions for uid on path. */
+    int GetTransforms(const std::string& path, uid_t uid);
+
+    /** Transforms from src to dst file */
+    bool Transform(const std::string& src, const std::string& dst, int transforms, uid_t uid);
+
     /**
      * Determines if to allow FUSE_LOOKUP for uid. Might allow uids that don't belong to the
      * MediaProvider user, depending on OEM configuration.
@@ -206,6 +215,9 @@
     jmethodID mid_on_file_created_;
     jmethodID mid_should_allow_lookup_;
     jmethodID mid_is_app_clone_user_;
+    jmethodID mid_get_io_path_;
+    jmethodID mid_get_transforms_;
+    jmethodID mid_transform_;
 
     /**
      * Auxiliary for caching MediaProvider methods.
diff --git a/jni/node-inl.h b/jni/node-inl.h
index dfd8141..b635a1c 100644
--- a/jni/node-inl.h
+++ b/jni/node-inl.h
@@ -19,6 +19,7 @@
 
 #include <android-base/logging.h>
 
+#include <atomic>
 #include <cstdint>
 #include <limits>
 #include <list>
@@ -40,13 +41,15 @@
 namespace fuse {
 
 struct handle {
-    explicit handle(int fd, const RedactionInfo* ri, bool cached) : fd(fd), ri(ri), cached(cached) {
+    explicit handle(int fd, const RedactionInfo* ri, bool cached, uid_t uid)
+        : fd(fd), ri(ri), cached(cached), uid(uid) {
         CHECK(ri != nullptr);
     }
 
     const int fd;
     const std::unique_ptr<const RedactionInfo> ri;
     const bool cached;
+    const uid_t uid;
 
     ~handle() { close(fd); }
 };
@@ -114,13 +117,14 @@
 class node {
   public:
     // Creates a new node with the specified parent, name and lock.
-    static node* Create(node* parent, const std::string& name, std::recursive_mutex* lock,
+    static node* Create(node* parent, const std::string& name, const std::string& io_path,
+                        bool transforms_complete, const int transforms, std::recursive_mutex* lock,
                         NodeTracker* tracker) {
         // Place the entire constructor under a critical section to make sure
         // node creation, tracking (if enabled) and the addition to a parent are
         // atomic.
         std::lock_guard<std::recursive_mutex> guard(*lock);
-        return new node(parent, name, lock, tracker);
+        return new node(parent, name, io_path, transforms_complete, transforms, lock, tracker);
     }
 
     // Creates a new root node. Root nodes have no parents by definition
@@ -128,7 +132,7 @@
     static node* CreateRoot(const std::string& path, std::recursive_mutex* lock,
                             NodeTracker* tracker) {
         std::lock_guard<std::recursive_mutex> guard(*lock);
-        node* root = new node(nullptr, path, lock, tracker);
+        node* root = new node(nullptr, path, path, true, 0, lock, tracker);
 
         // The root always has one extra reference to avoid it being
         // accidentally collected.
@@ -176,36 +180,40 @@
 
     // Looks up a direct descendant of this node by name. If |acquire| is true,
     // also Acquire the node before returning a reference to it.
-    node* LookupChildByName(const std::string& name, bool acquire) const {
-        std::lock_guard<std::recursive_mutex> guard(*lock_);
-
-        // lower_bound will give us the first child with strcasecmp(child->name, name) >=0.
-        // For more context see comment on the NodeCompare struct.
-        auto start = children_.lower_bound(std::make_pair(name, 0));
-        // upper_bound will give us the first child with strcasecmp(child->name, name) > 0
-        auto end =
-                children_.upper_bound(std::make_pair(name, std::numeric_limits<uintptr_t>::max()));
-        for (auto it = start; it != end; it++) {
-            node* child = *it;
-            if (!child->deleted_) {
+    node* LookupChildByName(const std::string& name, bool acquire, const int transforms = 0) const {
+        return ForChild(name, [acquire, transforms](node* child) {
+            if (child->transforms_ == transforms) {
                 if (acquire) {
                     child->Acquire();
                 }
-                return child;
+                return true;
             }
-        }
-        return nullptr;
+            return false;
+        });
     }
 
-    // Marks this node as deleted. It is still associated with its parent, and
-    // all open handles etc. to this node are preserved until its refcount goes
+    // Marks this node children as deleted. They are still associated with their parent, and
+    // all open handles etc. to the deleted nodes are preserved until their refcount goes
     // to zero.
+    void SetDeletedForChild(const std::string& name) {
+        ForChild(name, [](node* child) {
+            child->SetDeleted();
+            return false;
+        });
+    }
+
     void SetDeleted() {
         std::lock_guard<std::recursive_mutex> guard(*lock_);
-
         deleted_ = true;
     }
 
+    void RenameChild(const std::string& old_name, const std::string& new_name, node* new_parent) {
+        ForChild(old_name, [=](node* child) {
+            child->Rename(new_name, new_parent);
+            return false;
+        });
+    }
+
     void Rename(const std::string& name, node* new_parent) {
         std::lock_guard<std::recursive_mutex> guard(*lock_);
 
@@ -252,6 +260,16 @@
         return name_;
     }
 
+    const std::string& GetIoPath() const { return io_path_; }
+
+    int GetTransforms() const { return transforms_; }
+
+    bool IsTransformsComplete() const {
+        return transforms_complete_.load(std::memory_order_acquire);
+    }
+
+    void SetTransformsComplete() { transforms_complete_.store(true, std::memory_order_release); }
+
     node* GetParent() const {
         std::lock_guard<std::recursive_mutex> guard(*lock_);
         return parent_;
@@ -325,8 +343,12 @@
     static const node* LookupAbsolutePath(const node* root, const std::string& absolute_path);
 
   private:
-    node(node* parent, const std::string& name, std::recursive_mutex* lock, NodeTracker* tracker)
+    node(node* parent, const std::string& name, const std::string& io_path, bool transforms_complete,
+         const int transforms, std::recursive_mutex* lock, NodeTracker* tracker)
         : name_(name),
+          io_path_(io_path),
+          transforms_complete_(transforms_complete),
+          transforms_(transforms),
           refcount_(0),
           parent_(nullptr),
           has_redacted_cache_(false),
@@ -381,6 +403,32 @@
         }
     }
 
+    // Finds *all* non-deleted nodes matching |name| and runs the function |callback| on each
+    // node until |callback| returns true.
+    // When |callback| returns true, the matched node is returned
+    node* ForChild(const std::string& name, const std::function<bool(node*)>& callback) const {
+        std::lock_guard<std::recursive_mutex> guard(*lock_);
+
+        // lower_bound will give us the first child with strcasecmp(child->name, name) >=0.
+        // For more context see comment on the NodeCompare struct.
+        auto start = children_.lower_bound(std::make_pair(name, 0));
+        // upper_bound will give us the first child with strcasecmp(child->name, name) > 0
+        auto end =
+                children_.upper_bound(std::make_pair(name, std::numeric_limits<uintptr_t>::max()));
+
+        // Make a copy of the matches because calling callback might modify the list which will
+        // cause issues while iterating over them.
+        std::vector<node*> children(start, end);
+
+        for (node* child : children) {
+            if (!child->deleted_ && callback(child)) {
+                return child;
+            }
+        }
+
+        return nullptr;
+    }
+
     // A custom heterogeneous comparator used for set of this node's children_ to speed up child
     // node by name lookups.
     //
@@ -427,6 +475,15 @@
 
     // The name of this node. Non-const because it can change during renames.
     std::string name_;
+    // Filesystem path that will be used for IO (if it is non-empty) instead of node->BuildPath
+    const std::string io_path_;
+    // Whether any transforms required on |io_path_| are complete.
+    // If false, might need to call a node transform function with |transforms| below
+    std::atomic_bool transforms_complete_;
+    // Opaque flags that determine the 'supported' and 'required' transforms to perform on node
+    // before IO. These flags should not be interpreted in native but should be passed as part
+    // of a transform function and if successful, |transforms_complete_| should be set to true
+    const int transforms_;
     // The reference count for this node. Guarded by |lock_|.
     uint32_t refcount_;
     // Set of children of this node. All of them contain a back reference
diff --git a/jni/node_test.cpp b/jni/node_test.cpp
index 357cea8..e502dbe 100644
--- a/jni/node_test.cpp
+++ b/jni/node_test.cpp
@@ -31,8 +31,14 @@
 
     typedef std::unique_ptr<node, decltype(&NodeTest::destroy)> unique_node_ptr;
 
-    unique_node_ptr CreateNode(node* parent, const std::string& path) {
-        return unique_node_ptr(node::Create(parent, path, &lock_, &tracker_), &NodeTest::destroy);
+    unique_node_ptr CreateNode(node* parent, const std::string& path, const int transforms = 0) {
+        return unique_node_ptr(node::Create(parent, path, "", true, transforms, &lock_, &tracker_),
+                               &NodeTest::destroy);
+    }
+
+    static class node* ForChild(class node* node, const std::string& name,
+                                const std::function<bool(class node*)>& callback) {
+        return node->ForChild(name, callback);
     }
 
     // Expose NodeCompare for testing.
@@ -61,7 +67,7 @@
 }
 
 TEST_F(NodeTest, TestRelease) {
-    node* node = node::Create(nullptr, "/path", &lock_, &tracker_);
+    node* node = node::Create(nullptr, "/path", "", true, 0, &lock_, &tracker_);
     acquire(node);
     acquire(node);
     ASSERT_EQ(3, GetRefCount(node));
@@ -77,7 +83,7 @@
     ASSERT_TRUE(node->Release(2));
 }
 
-TEST_F(NodeTest, TestRenameWithName) {
+TEST_F(NodeTest, TestRenameName) {
     unique_node_ptr parent = CreateNode(nullptr, "/path");
 
     unique_node_ptr child = CreateNode(parent.get(), "subdir");
@@ -94,7 +100,7 @@
     ASSERT_EQ(1, GetRefCount(child.get()));
 }
 
-TEST_F(NodeTest, TestRenameWithParent) {
+TEST_F(NodeTest, TestRenameParent) {
     unique_node_ptr parent1 = CreateNode(nullptr, "/path1");
     unique_node_ptr parent2 = CreateNode(nullptr, "/path2");
 
@@ -113,7 +119,7 @@
     ASSERT_EQ(1, GetRefCount(child.get()));
 }
 
-TEST_F(NodeTest, TestRenameWithNameAndParent) {
+TEST_F(NodeTest, TestRenameNameAndParent) {
     unique_node_ptr parent1 = CreateNode(nullptr, "/path1");
     unique_node_ptr parent2 = CreateNode(nullptr, "/path2");
 
@@ -133,6 +139,101 @@
     ASSERT_EQ(1, GetRefCount(child.get()));
 }
 
+TEST_F(NodeTest, TestRenameNameForChild) {
+    unique_node_ptr parent = CreateNode(nullptr, "/path");
+
+    unique_node_ptr child0 = CreateNode(parent.get(), "subdir", 0 /* transforms */);
+    unique_node_ptr child1 = CreateNode(parent.get(), "subdir", 1 /* transforms */);
+    ASSERT_EQ(3, GetRefCount(parent.get()));
+    ASSERT_EQ(child0.get(),
+              parent->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+
+    parent->RenameChild("subdir", "subdir_new", parent.get());
+
+    ASSERT_EQ(3, GetRefCount(parent.get()));
+    ASSERT_EQ(nullptr,
+              parent->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+    ASSERT_EQ(child0.get(),
+              parent->LookupChildByName("subdir_new", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent->LookupChildByName("subdir_new", false /* acquire */, 1 /* transforms */));
+
+    ASSERT_EQ("/path/subdir_new", child0->BuildPath());
+    ASSERT_EQ("/path/subdir_new", child1->BuildPath());
+    ASSERT_EQ(1, GetRefCount(child0.get()));
+    ASSERT_EQ(1, GetRefCount(child1.get()));
+}
+
+TEST_F(NodeTest, TestRenameParentForChild) {
+    unique_node_ptr parent1 = CreateNode(nullptr, "/path1");
+    unique_node_ptr parent2 = CreateNode(nullptr, "/path2");
+
+    unique_node_ptr child0 = CreateNode(parent1.get(), "subdir", 0 /* transforms */);
+    unique_node_ptr child1 = CreateNode(parent1.get(), "subdir", 1 /* transforms */);
+    ASSERT_EQ(3, GetRefCount(parent1.get()));
+    ASSERT_EQ(child0.get(),
+              parent1->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent1->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+
+    parent1->RenameChild("subdir", "subdir", parent2.get());
+    ASSERT_EQ(1, GetRefCount(parent1.get()));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+
+    ASSERT_EQ(3, GetRefCount(parent2.get()));
+    ASSERT_EQ(child0.get(),
+              parent2->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent2->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+
+    ASSERT_EQ("/path2/subdir", child0->BuildPath());
+    ASSERT_EQ("/path2/subdir", child1->BuildPath());
+    ASSERT_EQ(1, GetRefCount(child0.get()));
+    ASSERT_EQ(1, GetRefCount(child1.get()));
+}
+
+TEST_F(NodeTest, TestRenameNameAndParentForChild) {
+    unique_node_ptr parent1 = CreateNode(nullptr, "/path1");
+    unique_node_ptr parent2 = CreateNode(nullptr, "/path2");
+
+    unique_node_ptr child0 = CreateNode(parent1.get(), "subdir", 0 /* transforms */);
+    unique_node_ptr child1 = CreateNode(parent1.get(), "subdir", 1 /* transforms */);
+    ASSERT_EQ(3, GetRefCount(parent1.get()));
+    ASSERT_EQ(child0.get(),
+              parent1->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent1->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+
+    parent1->RenameChild("subdir", "subdir_new", parent2.get());
+    ASSERT_EQ(1, GetRefCount(parent1.get()));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir_new", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir_new", false /* acquire */, 1 /* transforms */));
+
+    ASSERT_EQ(3, GetRefCount(parent2.get()));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir_new", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent1->LookupChildByName("subdir_new", false /* acquire */, 1 /* transforms */));
+
+    ASSERT_EQ("/path2/subdir_new", child0->BuildPath());
+    ASSERT_EQ("/path2/subdir_new", child1->BuildPath());
+    ASSERT_EQ(1, GetRefCount(child0.get()));
+    ASSERT_EQ(1, GetRefCount(child1.get()));
+}
+
 TEST_F(NodeTest, TestBuildPath) {
     unique_node_ptr parent = CreateNode(nullptr, "/path");
     ASSERT_EQ("/path", parent->BuildPath());
@@ -156,14 +257,30 @@
     ASSERT_EQ(nullptr, parent->LookupChildByName("subdir", false /* acquire */));
 }
 
+TEST_F(NodeTest, TestSetDeletedForChild) {
+    unique_node_ptr parent = CreateNode(nullptr, "/path");
+    unique_node_ptr child0 = CreateNode(parent.get(), "subdir", 0 /* transforms */);
+    unique_node_ptr child1 = CreateNode(parent.get(), "subdir", 1 /* transforms */);
+
+    ASSERT_EQ(child0.get(),
+              parent->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+    parent->SetDeletedForChild("subdir");
+    ASSERT_EQ(nullptr,
+              parent->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+}
+
 TEST_F(NodeTest, DeleteTree) {
     unique_node_ptr parent = CreateNode(nullptr, "/path");
 
     // This is the tree that we intend to delete.
-    node* child = node::Create(parent.get(), "subdir", &lock_, &tracker_);
-    node::Create(child, "s1", &lock_, &tracker_);
-    node* subchild2 = node::Create(child, "s2", &lock_, &tracker_);
-    node::Create(subchild2, "sc2", &lock_, &tracker_);
+    node* child = node::Create(parent.get(), "subdir", "", true, 0, &lock_, &tracker_);
+    node::Create(child, "s1", "", true, 0, &lock_, &tracker_);
+    node* subchild2 = node::Create(child, "s2", "", true, 0, &lock_, &tracker_);
+    node::Create(subchild2, "sc2", "", true, 0, &lock_, &tracker_);
 
     ASSERT_EQ(child, parent->LookupChildByName("subdir", false /* acquire */));
     node::DeleteTree(child);
@@ -178,6 +295,20 @@
     ASSERT_EQ(nullptr, parent->LookupChildByName("", false /* acquire */));
 }
 
+TEST_F(NodeTest, LookupChildByName_transforms) {
+    unique_node_ptr parent = CreateNode(nullptr, "/path");
+    unique_node_ptr child0 = CreateNode(parent.get(), "subdir", 0 /* transforms */);
+    unique_node_ptr child1 = CreateNode(parent.get(), "subdir", 1 /* transforms */);
+
+    ASSERT_EQ(child0.get(), parent->LookupChildByName("subdir", false /* acquire */));
+    ASSERT_EQ(child0.get(),
+              parent->LookupChildByName("subdir", false /* acquire */, 0 /* transforms */));
+    ASSERT_EQ(child1.get(),
+              parent->LookupChildByName("subdir", false /* acquire */, 1 /* transforms */));
+    ASSERT_EQ(nullptr,
+              parent->LookupChildByName("subdir", false /* acquire */, 2 /* transforms */));
+}
+
 TEST_F(NodeTest, LookupChildByName_refcounts) {
     unique_node_ptr parent = CreateNode(nullptr, "/path");
     unique_node_ptr child = CreateNode(parent.get(), "subdir");
@@ -217,7 +348,8 @@
 TEST_F(NodeTest, AddDestroyHandle) {
     unique_node_ptr node = CreateNode(nullptr, "/path");
 
-    handle* h = new handle(-1, new mediaprovider::fuse::RedactionInfo, true /* cached */);
+    handle* h =
+            new handle(-1, new mediaprovider::fuse::RedactionInfo, true /* cached */, 0 /* uid */);
     node->AddHandle(h);
     ASSERT_TRUE(node->HasCachedHandle());
 
@@ -229,7 +361,7 @@
     EXPECT_DEATH(node->DestroyHandle(h), "");
     EXPECT_DEATH(node->DestroyHandle(nullptr), "");
     std::unique_ptr<handle> h2(
-            new handle(-1, new mediaprovider::fuse::RedactionInfo, true /* cached */));
+            new handle(-1, new mediaprovider::fuse::RedactionInfo, true /* cached */, 0 /* uid */));
     EXPECT_DEATH(node->DestroyHandle(h2.get()), "");
 }
 
@@ -318,3 +450,44 @@
     test_fn("bAr", bar1.get(), bar2.get());
     test_fn("BaZ", baz1.get(), baz2.get());
 }
+
+TEST_F(NodeTest, ForChild) {
+    unique_node_ptr parent = CreateNode(nullptr, "/path");
+    unique_node_ptr foo1 = CreateNode(parent.get(), "FoO");
+    unique_node_ptr foo2 = CreateNode(parent.get(), "fOo");
+    unique_node_ptr foo3 = CreateNode(parent.get(), "foo");
+    foo3->SetDeleted();
+
+    std::vector<node*> match_all;
+    auto test_fn_match_all = [&](node* child) {
+        match_all.push_back(child);
+        return false;
+    };
+
+    std::vector<node*> match_first;
+    auto test_fn_match_first = [&](node* child) {
+        match_first.push_back(child);
+        return true;
+    };
+
+    std::vector<node*> match_none;
+    auto test_fn_match_none = [&](node* child) {
+        match_none.push_back(child);
+        return false;
+    };
+
+    node* node_all = ForChild(parent.get(), "foo", test_fn_match_all);
+    ASSERT_EQ(nullptr, node_all);
+    ASSERT_EQ(2, match_all.size());
+    ASSERT_EQ(std::min(foo1.get(), foo2.get()), match_all[0]);
+    ASSERT_EQ(std::max(foo1.get(), foo2.get()), match_all[1]);
+
+    node* node_first = ForChild(parent.get(), "foo", test_fn_match_first);
+    ASSERT_EQ(std::min(foo1.get(), foo2.get()), node_first);
+    ASSERT_EQ(1, match_first.size());
+    ASSERT_EQ(std::min(foo1.get(), foo2.get()), match_first[0]);
+
+    node* node_none = ForChild(parent.get(), "bar", test_fn_match_none);
+    ASSERT_EQ(nullptr, node_none);
+    ASSERT_TRUE(match_none.empty());
+}
diff --git a/res/layout/photo_picker.xml b/res/layout/photo_picker.xml
new file mode 100644
index 0000000..073a8bd
--- /dev/null
+++ b/res/layout/photo_picker.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT 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"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              tools:context=".MainActivity">
+
+    <Button
+        android:id="@+id/button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Give up"
+        />
+
+    <ListView
+        android:id="@+id/names_list"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        />
+
+</LinearLayout>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 09a1296..1d7c7db 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> bykomende items</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> bykomende item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Vee tydelike programlêers uit"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vee tydelike programlêers uit?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> wil \'n paar tydelike lêers uitvee. Dit kan verhoogde batterygebruik of sellulêre data tot gevolg hê."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Vee tans tydelike programlêers uit …"</string>
-    <string name="clear" msgid="5524638938415865915">"Vee uit"</string>
     <string name="allow" msgid="8885707816848569619">"Laat toe"</string>
     <string name="deny" msgid="6040983710442068936">"Weier"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 1a62bf5..ec43b10 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">እንዲሁም <xliff:g id="COUNT_1">^1</xliff:g> ተጨማሪ ንጥሎች</item>
       <item quantity="other">እንዲሁም <xliff:g id="COUNT_1">^1</xliff:g> ተጨማሪ ንጥሎች</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ጊዜያዊ የመተግበሪያ ፋይሎች ይጸዱ?"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ጊዜያዊ የመተግበሪያ ፋይሎች ይጽዱ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> አንዳንድ ጊዜያዊ ፋይሎችን ማጽዳት ይፈልጋል። ይህ የበለጠ የባትሪ ኃይል ወይም የተንቀሳቃሽ ስልክ ውሂብ ፍጆታን ሊጨምር ይችላል።"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ጊዜያዊ የመተግበሪያ ፋይሎችን በማጽዳት ላይ…"</string>
-    <string name="clear" msgid="5524638938415865915">"አጽዳ"</string>
     <string name="allow" msgid="8885707816848569619">"ፍቀድ"</string>
     <string name="deny" msgid="6040983710442068936">"ከልክል"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index c5d7cea..74d70be 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -23,7 +23,7 @@
     <string name="unknown" msgid="2059049215682829375">"غير معروف"</string>
     <string name="root_images" msgid="5861633549189045666">"الصور"</string>
     <string name="root_videos" msgid="8792703517064649453">"الفيديوهات"</string>
-    <string name="root_audio" msgid="3505830755201326018">"صوتيات"</string>
+    <string name="root_audio" msgid="3505830755201326018">"الصوت"</string>
     <string name="root_documents" msgid="3829103301363849237">"المستندات"</string>
     <string name="permission_required" msgid="1460820436132943754">"مطلوب الحصول على إذن لتعديل هذا العنصر أو حذفه."</string>
     <string name="permission_required_action" msgid="706370952366113539">"متابعة"</string>
@@ -45,10 +45,8 @@
       <item quantity="other">و<xliff:g id="COUNT_1">^1</xliff:g> عنصر إضافي</item>
       <item quantity="one">وعنصر إضافي واحد (<xliff:g id="COUNT_0">^1</xliff:g>)</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"محو ملفات التطبيق المؤقتة"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"هل تريد محو ملفات التطبيق المؤقتة؟"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"يريد تطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> محو بعض الملفات المؤقتة. قد يؤدي هذا إلى زيادة استهلاك شحن البطارية أو بيانات شبكة الجوّال."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"جارٍ محو ملفات التطبيق المؤقتة…"</string>
-    <string name="clear" msgid="5524638938415865915">"محو"</string>
     <string name="allow" msgid="8885707816848569619">"سماح"</string>
     <string name="deny" msgid="6040983710442068936">"رفض"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index be897a1..8bbc109 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">আৰু <xliff:g id="COUNT_1">^1</xliff:g> টা অতিৰিক্ত বস্তু</item>
       <item quantity="other">আৰু <xliff:g id="COUNT_1">^1</xliff:g> টা অতিৰিক্ত বস্তু</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"অস্থায়ী এপ্‌ ফাইলসমূহ মচক"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"অস্থায়ী এপ্‌ ফাইলসমূহ মচিবনে?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>এ কিছুমান অস্থায়ী ফাইল মচিব বিচাৰিছে। ইয়াৰ ফলত বেটাৰী অথবা চেলুলাৰ ডেটাৰ ব্যৱহাৰ বৃদ্ধি হ’ব পাৰে।"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"অস্থায়ী এপ্‌ ফাইলসমূহ মচি থকা হৈছে…"</string>
-    <string name="clear" msgid="5524638938415865915">"মচক"</string>
     <string name="allow" msgid="8885707816848569619">"অনুমতি দিয়ক"</string>
     <string name="deny" msgid="6040983710442068936">"অস্বীকাৰ কৰক"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index a8d2ab3..988aeff 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Üstəgəl <xliff:g id="COUNT_1">^1</xliff:g> əlavə element</item>
       <item quantity="one">Üstəgəl <xliff:g id="COUNT_0">^1</xliff:g> əlavə element</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Müvəqqəti tətbiq fayllarını silin"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Müvəqqəti tətbiq faylları silinsin?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bəzi müvəqqəti faylları silmək istəyir. Bu, batareya və ya mobil data istifadəsinin artmasına səbəb ola bilər."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Müvəqqəti tətbiq faylları silinir…"</string>
-    <string name="clear" msgid="5524638938415865915">"Silin"</string>
     <string name="allow" msgid="8885707816848569619">"İcazə verin"</string>
     <string name="deny" msgid="6040983710442068936">"Rədd edin"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 9756151..feb033d 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -39,10 +39,8 @@
       <item quantity="few">I još <xliff:g id="COUNT_1">^1</xliff:g> stavke</item>
       <item quantity="other">I još <xliff:g id="COUNT_1">^1</xliff:g> stavki</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Obrišite privremene datoteke aplikacija"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Želite li da obrišete privremene datoteke aplikacija?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> želi da obriše neke privremene datoteke. Ovo može da dovede do povećane potrošnje baterije ili mobilnih podataka."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Brišu se privremene datoteke aplikacija…"</string>
-    <string name="clear" msgid="5524638938415865915">"Obriši"</string>
     <string name="allow" msgid="8885707816848569619">"Dozvoli"</string>
     <string name="deny" msgid="6040983710442068936">"Odbij"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 58bffee..b73ff00 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="many">Плюс <xliff:g id="COUNT_1">^1</xliff:g> дадатковых элементаў</item>
       <item quantity="other">Плюс <xliff:g id="COUNT_1">^1</xliff:g> дадатковага элемента</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ачысціць часовыя файлы праграм"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Ачысціць часовыя файлы праграм?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> запытвае дазвол на выдаленне некаторых часовых файлаў. У сувязі з гэтым можа павялічыцца ўзровень выкарыстання акумулятара ці памер сотавай перадачы даных."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Выдаляюцца часовыя файлы праграм…"</string>
-    <string name="clear" msgid="5524638938415865915">"Ачысціць"</string>
     <string name="allow" msgid="8885707816848569619">"Дазволіць"</string>
     <string name="deny" msgid="6040983710442068936">"Адмовіць"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index b576228..d160870 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">И още <xliff:g id="COUNT_1">^1</xliff:g> допълнителни елемента</item>
       <item quantity="one">И още <xliff:g id="COUNT_0">^1</xliff:g> допълнителен елемент</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Изчистване на временните файлове на приложенията"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Да се изчистят ли временните файлове на приложенията?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> иска да изчисти някои временни файлове. Това може да доведе до увеличено използване на батерията или мобилните данни."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Временните файлове на приложенията се изчистват…"</string>
-    <string name="clear" msgid="5524638938415865915">"Изчистване"</string>
     <string name="allow" msgid="8885707816848569619">"Разрешаване"</string>
     <string name="deny" msgid="6040983710442068936">"Отказ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 552556e..8de6cb5 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">এছাড়াও <xliff:g id="COUNT_1">^1</xliff:g>টি অতিরিক্ত আইটেম</item>
       <item quantity="other">এছাড়াও <xliff:g id="COUNT_1">^1</xliff:g>টি অতিরিক্ত আইটেম</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"অস্থায়ী অ্যাপ ফাইলগুলি খালি করুন"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"অস্থায়ী অ্যাপ ফাইল মুছে দিতে চান?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> কিছু অস্থায়ী ফাইলকে মুছে দিতে চায়। এর ফলে, ব্যাটারি বা মোবাইল ডেটা বেশি খরচ হতে পারে।"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"অস্থায়ী অ্যাপ ফাইল মুছে ফেলা হচ্ছে…"</string>
-    <string name="clear" msgid="5524638938415865915">"সরান"</string>
     <string name="allow" msgid="8885707816848569619">"অনুমতি দিন"</string>
     <string name="deny" msgid="6040983710442068936">"বাতিল করুন"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 9f89481..9aa39e6 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -39,10 +39,8 @@
       <item quantity="few">Još <xliff:g id="COUNT_1">^1</xliff:g> dodatne stavke</item>
       <item quantity="other">Još <xliff:g id="COUNT_1">^1</xliff:g> dodatnih stavki</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Brisanje privremenih fajlova aplikacija"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Obrisati privremene fajlove aplikacija?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> želi obrisati neke privremene fajlove. Ovo može dovesti do povećanog korištenja baterije ili prijenosa podataka na mobilnoj mreži."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Brisanje privremenih fajlova aplikacije…"</string>
-    <string name="clear" msgid="5524638938415865915">"Obriši"</string>
     <string name="allow" msgid="8885707816848569619">"Dozvoli"</string>
     <string name="deny" msgid="6040983710442068936">"Odbij"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 184a9b9..b23455f 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">^1</xliff:g> elements addicionals més</item>
       <item quantity="one"><xliff:g id="COUNT_0">^1</xliff:g> element addicional més</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Esborra fitxers temporals d\'aplicacions"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vols esborrar els fitxers temporals d\'aplicacions?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vol esborrar alguns fitxers temporals. Això pot suposar un augment de l\'ús de la bateria o de les dades mòbils."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"S\'estan esborrant els fitxers temporals d\'aplicacions…"</string>
-    <string name="clear" msgid="5524638938415865915">"Esborra"</string>
     <string name="allow" msgid="8885707816848569619">"Permet"</string>
     <string name="deny" msgid="6040983710442068936">"Denega"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 3fa3e40..bc92886 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> dalších položek</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> další položka</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Vymazání dočasných souborů aplikací"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vymazat dočasné soubory aplikací?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Aplikace <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> chce vymazat nějaké dočasné soubory. Tato akce může vést ke zvýšenému využití baterie nebo mobilních dat."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Mazání dočasných souborů aplikace…"</string>
-    <string name="clear" msgid="5524638938415865915">"Vymazat"</string>
     <string name="allow" msgid="8885707816848569619">"Povolit"</string>
     <string name="deny" msgid="6040983710442068936">"Zakázat"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 96ee522..181ea3e 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -19,7 +19,7 @@
     <string name="uid_label" msgid="8421971615411294156">"Medier"</string>
     <string name="storage_description" msgid="4081716890357580107">"Lokalt lager"</string>
     <string name="app_label" msgid="9035307001052716210">"Medielagring"</string>
-    <string name="artist_label" msgid="8105600993099120273">"Kunstner"</string>
+    <string name="artist_label" msgid="8105600993099120273">"Musiker"</string>
     <string name="unknown" msgid="2059049215682829375">"Ukendt"</string>
     <string name="root_images" msgid="5861633549189045666">"Billeder"</string>
     <string name="root_videos" msgid="8792703517064649453">"Videoer"</string>
@@ -37,10 +37,8 @@
       <item quantity="one">Plus <xliff:g id="COUNT_1">^1</xliff:g> andet element</item>
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> andre elementer</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ryd midlertidige appfiler"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vil du rydde midlertidige appfiler?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vil gerne rydde nogle midlertidige filer. Dette kan resultere i øget forbrug af batteri eller mobildata."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Rydder midlertidige appfiler…"</string>
-    <string name="clear" msgid="5524638938415865915">"Ryd"</string>
     <string name="allow" msgid="8885707816848569619">"Tillad"</string>
     <string name="deny" msgid="6040983710442068936">"Afvis"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 8b19ff5..07f2c1f 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">^1</xliff:g> weitere Elemente</item>
       <item quantity="one"><xliff:g id="COUNT_0">^1</xliff:g> weiteres Element</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Temporäre App-Dateien löschen"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Temporäre App-Dateien löschen?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> möchte einige temporäre Dateien löschen. Dadurch können Akkuverbrauch und mobile Datennutzung steigen."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Temporäre App-Dateien werden gelöscht…"</string>
-    <string name="clear" msgid="5524638938415865915">"Löschen"</string>
     <string name="allow" msgid="8885707816848569619">"Zulassen"</string>
     <string name="deny" msgid="6040983710442068936">"Ablehnen"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 7045ca0..c30faf6 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Συν <xliff:g id="COUNT_1">^1</xliff:g> επιπλέον στοιχεία</item>
       <item quantity="one">Συν <xliff:g id="COUNT_0">^1</xliff:g> επιπλέον στοιχείο</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Διαγραφή προσωρινών αρχείων εφαρμογών"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Να διαγραφούν τα προσωρινά αρχεία εφαρμογών;"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Η εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> θέλει να διαγράψει ορισμένα προσωρινά αρχεία. Αυτό μπορεί να οδηγήσει σε αυξημένη χρήση μπαταριών ή δεδομένων κινητής τηλεφωνίας."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Διαγραφή προσωρινών αρχείων εφαρμογών…"</string>
-    <string name="clear" msgid="5524638938415865915">"Διαγραφή"</string>
     <string name="allow" msgid="8885707816848569619">"Να επιτρέπεται"</string>
     <string name="deny" msgid="6040983710442068936">"Απόρριψη"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 1205a7e..42fbc5b 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> additional items</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> additional item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Clear temporary app files"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Clear temporary app files?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> would like to clear some temporary files. This may result in an increased usage of battery or mobile data."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Clearing temporary app files…"</string>
-    <string name="clear" msgid="5524638938415865915">"Clear"</string>
     <string name="allow" msgid="8885707816848569619">"Allow"</string>
     <string name="deny" msgid="6040983710442068936">"Deny"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 1205a7e..42fbc5b 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> additional items</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> additional item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Clear temporary app files"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Clear temporary app files?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> would like to clear some temporary files. This may result in an increased usage of battery or mobile data."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Clearing temporary app files…"</string>
-    <string name="clear" msgid="5524638938415865915">"Clear"</string>
     <string name="allow" msgid="8885707816848569619">"Allow"</string>
     <string name="deny" msgid="6040983710442068936">"Deny"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 1205a7e..42fbc5b 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> additional items</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> additional item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Clear temporary app files"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Clear temporary app files?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> would like to clear some temporary files. This may result in an increased usage of battery or mobile data."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Clearing temporary app files…"</string>
-    <string name="clear" msgid="5524638938415865915">"Clear"</string>
     <string name="allow" msgid="8885707816848569619">"Allow"</string>
     <string name="deny" msgid="6040983710442068936">"Deny"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 1205a7e..42fbc5b 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> additional items</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> additional item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Clear temporary app files"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Clear temporary app files?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> would like to clear some temporary files. This may result in an increased usage of battery or mobile data."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Clearing temporary app files…"</string>
-    <string name="clear" msgid="5524638938415865915">"Clear"</string>
     <string name="allow" msgid="8885707816848569619">"Allow"</string>
     <string name="deny" msgid="6040983710442068936">"Deny"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 18ba860..8bbcd26 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎Plus ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">^1</xliff:g>‎‏‎‎‏‏‏‎ additional items‎‏‎‎‏‎</item>
       <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎Plus ‎‏‎‎‏‏‎<xliff:g id="COUNT_0">^1</xliff:g>‎‏‎‎‏‏‏‎ additional item‎‏‎‎‏‎</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎Clear temporary app files‎‏‎‎‏‎"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎Clear temporary app files?‎‏‎‎‏‎"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>‎‏‎‎‏‏‏‎ would like to clear some temporary files. This may result in an increased usage of battery or cellular data.‎‏‎‎‏‎"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎Clearing temporary app files…‎‏‎‎‏‎"</string>
-    <string name="clear" msgid="5524638938415865915">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎Clear‎‏‎‎‏‎"</string>
     <string name="allow" msgid="8885707816848569619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎Allow‎‏‎‎‏‎"</string>
     <string name="deny" msgid="6040983710442068936">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‎Deny‎‏‎‎‏‎"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index e2ffe99..67c0e30 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">^1</xliff:g> elementos adicionales</item>
       <item quantity="one"><xliff:g id="COUNT_0">^1</xliff:g> elemento adicional</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Borra archivos temporales de apps"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"¿Deseas borrar archivos temporales de apps?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> quiere borrar algunos archivos temporales, lo que podría ocasionar un mayor uso de la batería o los datos móviles."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Borrando archivos temporales de apps…"</string>
-    <string name="clear" msgid="5524638938415865915">"Borrar"</string>
     <string name="allow" msgid="8885707816848569619">"Permitir"</string>
     <string name="deny" msgid="6040983710442068936">"Rechazar"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 7d0ee18..2b34dcd 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Y <xliff:g id="COUNT_1">^1</xliff:g> elementos más</item>
       <item quantity="one">Y <xliff:g id="COUNT_0">^1</xliff:g> elemento más</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Borrar archivos de aplicaciones temporales"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"¿Borrar archivos temporales de aplicaciones?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> quiere borrar algunos archivos temporales. Esta acción puede aumentar el uso de la batería o los datos móviles."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Borrando archivos temporales de aplicaciones…"</string>
-    <string name="clear" msgid="5524638938415865915">"Borrar"</string>
     <string name="allow" msgid="8885707816848569619">"Permitir"</string>
     <string name="deny" msgid="6040983710442068936">"Denegar"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 1dbfc5c..104bb9b 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Veel <xliff:g id="COUNT_1">^1</xliff:g> lisaüksust</item>
       <item quantity="one">Veel <xliff:g id="COUNT_0">^1</xliff:g> lisaüksus</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Rakenduse ajutiste failide kustutamine"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Kas soovite rakenduse ajutised failid kustutada?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> soovib kustutada mõned ajutised failid. See võib aku või mobiilse andmeside kasutust suurendada."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Rakenduse ajutiste failide kustutamine …"</string>
-    <string name="clear" msgid="5524638938415865915">"Kustuta"</string>
     <string name="allow" msgid="8885707816848569619">"Luba"</string>
     <string name="deny" msgid="6040983710442068936">"Keela"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 982a7c8..a85c489 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Eta beste <xliff:g id="COUNT_1">^1</xliff:g> elementu</item>
       <item quantity="one">Eta beste <xliff:g id="COUNT_0">^1</xliff:g> elementu</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Garbitu aplikazioen aldi baterako fitxategiak"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Aplikazioen aldi baterako fitxategiak garbitu nahi dituzu?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak aldi baterako fitxategi batzuk ezabatu nahi ditu. Ondorioz, baliteke bateria edo datu-konexioko datu gehiago erabiltzea."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Aplikazioaren aldi baterako fitxategiak garbitzen…"</string>
-    <string name="clear" msgid="5524638938415865915">"Garbitu"</string>
     <string name="allow" msgid="8885707816848569619">"Baimendu"</string>
     <string name="deny" msgid="6040983710442068936">"Ukatu"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index fc0d11e..de705e3 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -28,7 +28,7 @@
     <string name="permission_required" msgid="1460820436132943754">"برای اصلاح یا حذف این مورد مجوز لازم است."</string>
     <string name="permission_required_action" msgid="706370952366113539">"ادامه"</string>
     <string name="grant_dialog_button_allow" msgid="1644287024501033471">"مجاز"</string>
-    <string name="grant_dialog_button_deny" msgid="6190589471415815741">"مجاز نبودن"</string>
+    <string name="grant_dialog_button_deny" msgid="6190589471415815741">"رد کردن"</string>
     <plurals name="permission_more_thumb" formatted="false" msgid="4392079224649478923">
       <item quantity="one">‎+<xliff:g id="COUNT_1">^1</xliff:g>‎</item>
       <item quantity="other">‎+<xliff:g id="COUNT_1">^1</xliff:g>‎</item>
@@ -37,12 +37,10 @@
       <item quantity="one">به‌علاوه <xliff:g id="COUNT_1">^1</xliff:g> مورد دیگر</item>
       <item quantity="other">به‌علاوه <xliff:g id="COUNT_1">^1</xliff:g> مورد دیگر</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"پاک کردن فایل‌های موقت برنامه"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"فایل‌های موقت برنامه پاک شوند؟"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> می‌خواهد برخی از فایل‌های موقت را پاک کند. این کار ممکن است استفاده از باتری یا داده شبکه تلفن همراه را افزایش دهد."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"درحال پاک کردن فایل‌های موقتی برنامه…"</string>
-    <string name="clear" msgid="5524638938415865915">"پاک کردن"</string>
     <string name="allow" msgid="8885707816848569619">"اجازه دادن"</string>
-    <string name="deny" msgid="6040983710442068936">"مجاز نبودن"</string>
+    <string name="deny" msgid="6040983710442068936">"رد کردن"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
       <item quantity="one">به <xliff:g id="APP_NAME_1">^1</xliff:g> اجازه می‌دهید <xliff:g id="COUNT">^2</xliff:g> فایل صوتی را تغییر دهد؟</item>
       <item quantity="other">به <xliff:g id="APP_NAME_1">^1</xliff:g> اجازه می‌دهید <xliff:g id="COUNT">^2</xliff:g> فایل صوتی را تغییر دهد؟</item>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 39517ba..c100861 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Ja <xliff:g id="COUNT_1">^1</xliff:g> muuta asiaa</item>
       <item quantity="one">Ja <xliff:g id="COUNT_0">^1</xliff:g> muu asia</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Poista väliaikaisia sovellustiedostoja"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Poistetaanko väliaikaisia sovellustiedostoja?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> haluaa poistaa joitain väliaikaisia tiedostoja. Tämä voi lisätä akun tai mobiilidatan käyttöä."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Poistetaan väliaikaisia sovellustiedostoja…"</string>
-    <string name="clear" msgid="5524638938415865915">"Poista"</string>
     <string name="allow" msgid="8885707816848569619">"Salli"</string>
     <string name="deny" msgid="6040983710442068936">"Estä"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 021ba70..6ec897f 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Plus <xliff:g id="COUNT_1">^1</xliff:g> élément supplémentaire</item>
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> éléments supplémentaires</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Effacer les fichiers temporaires des applications"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Effacer les fichiers temporaires des applications?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aimerait supprimer certains fichiers temporaires. Ceci peut entraîner une utilisation accrue de la pile ou des données cellulaires."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Suppression des fichiers temporaires des applications en cours…"</string>
-    <string name="clear" msgid="5524638938415865915">"Effacer"</string>
     <string name="allow" msgid="8885707816848569619">"Autoriser"</string>
     <string name="deny" msgid="6040983710442068936">"Refuser"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 7b0d694..7c28423 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -30,81 +30,79 @@
     <string name="grant_dialog_button_allow" msgid="1644287024501033471">"Autoriser"</string>
     <string name="grant_dialog_button_deny" msgid="6190589471415815741">"Refuser"</string>
     <plurals name="permission_more_thumb" formatted="false" msgid="4392079224649478923">
-      <item quantity="one">+ <xliff:g id="COUNT_1">^1</xliff:g></item>
+      <item quantity="one">+<xliff:g id="COUNT_1">^1</xliff:g></item>
       <item quantity="other">+ <xliff:g id="COUNT_1">^1</xliff:g></item>
     </plurals>
     <plurals name="permission_more_text" formatted="false" msgid="7291997297174507324">
       <item quantity="one">Plus <xliff:g id="COUNT_1">^1</xliff:g> autre élément</item>
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> autres éléments</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Effacer les fichiers d\'application temporaires"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Effacer les fichiers d\'application temporaires ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> souhaite supprimer quelques fichiers temporaires, ce qui risque de solliciter davantage la batterie et le réseau de données mobiles."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Suppression des fichiers d\'application temporaires…"</string>
-    <string name="clear" msgid="5524638938415865915">"Effacer"</string>
     <string name="allow" msgid="8885707816848569619">"Autoriser"</string>
     <string name="deny" msgid="6040983710442068936">"Refuser"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichier audio ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> audio files?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichiers audio ?</item>
     </plurals>
     <plurals name="permission_write_video" formatted="false" msgid="1098082003326873084">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéo ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> videos?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéos ?</item>
     </plurals>
     <plurals name="permission_write_image" formatted="false" msgid="748745548893845892">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> photo ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> photos?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> photos ?</item>
     </plurals>
     <plurals name="permission_write_generic" formatted="false" msgid="3270172714743671779">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> élément ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> items?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> éléments ?</item>
     </plurals>
     <plurals name="permission_trash_audio" formatted="false" msgid="8907813869381755423">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> fichier audio dans la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> audio files to trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> fichiers audio dans la corbeille ?</item>
     </plurals>
     <plurals name="permission_trash_video" formatted="false" msgid="4672871911555787438">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> vidéo dans la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> videos to trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> vidéos dans la corbeille ?</item>
     </plurals>
     <plurals name="permission_trash_image" formatted="false" msgid="6400475304599873227">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> photo dans la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> photos to trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> photos dans la corbeille ?</item>
     </plurals>
     <plurals name="permission_trash_generic" formatted="false" msgid="3814167365075039711">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> élément dans la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> items to trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à placer <xliff:g id="COUNT">^2</xliff:g> éléments dans la corbeille ?</item>
     </plurals>
     <plurals name="permission_untrash_audio" formatted="false" msgid="7795265980168966321">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> fichier audio de la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> audio files out of trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> fichiers audio de la corbeille ?</item>
     </plurals>
     <plurals name="permission_untrash_video" formatted="false" msgid="332894888445508879">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> vidéo de la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> videos out of trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> vidéos de la corbeille ?</item>
     </plurals>
     <plurals name="permission_untrash_image" formatted="false" msgid="7024071378733595056">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> photo de la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> photos out of trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> photos de la corbeille ?</item>
     </plurals>
     <plurals name="permission_untrash_generic" formatted="false" msgid="6872817093731198374">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> élément de la corbeille ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to move <xliff:g id="COUNT">^2</xliff:g> items out of trash?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à retirer <xliff:g id="COUNT">^2</xliff:g> éléments de la corbeille ?</item>
     </plurals>
     <plurals name="permission_delete_audio" formatted="false" msgid="6848547621165184719">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> fichier audio ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to delete <xliff:g id="COUNT">^2</xliff:g> audio files?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> fichiers audio ?</item>
     </plurals>
     <plurals name="permission_delete_video" formatted="false" msgid="1251942606336748563">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> vidéo ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to delete <xliff:g id="COUNT">^2</xliff:g> videos?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> vidéos ?</item>
     </plurals>
     <plurals name="permission_delete_image" formatted="false" msgid="2303409455224710111">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> photo ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to delete <xliff:g id="COUNT">^2</xliff:g> photos?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> photos ?</item>
     </plurals>
     <plurals name="permission_delete_generic" formatted="false" msgid="1412218850351841181">
-      <item quantity="one">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> élément ?</item>
+      <item quantity="one">Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to delete <xliff:g id="COUNT">^2</xliff:g> items?</item>
       <item quantity="other">Autoriser l\'application <xliff:g id="APP_NAME_1">^1</xliff:g> à supprimer <xliff:g id="COUNT">^2</xliff:g> éléments ?</item>
     </plurals>
 </resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 93e281d..69eb572 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">E <xliff:g id="COUNT_1">^1</xliff:g> elementos adicionais</item>
       <item quantity="one">E <xliff:g id="COUNT_0">^1</xliff:g> elemento adicional</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Borrar os ficheiros temporais das aplicacións"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Queres borrar os ficheiros temporais da aplicación?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> quere borrar algúns ficheiros temporais. Por este motivo, pode aumentar o uso da batería e dos datos móbiles."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Borrando ficheiros temporais das aplicacións…"</string>
-    <string name="clear" msgid="5524638938415865915">"Borrar"</string>
     <string name="allow" msgid="8885707816848569619">"Permitir"</string>
     <string name="deny" msgid="6040983710442068936">"Denegar"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index e7c5619..47be764 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -22,8 +22,8 @@
     <string name="artist_label" msgid="8105600993099120273">"કલાકાર"</string>
     <string name="unknown" msgid="2059049215682829375">"અજાણ"</string>
     <string name="root_images" msgid="5861633549189045666">"છબીઓ"</string>
-    <string name="root_videos" msgid="8792703517064649453">"વીડિયો"</string>
-    <string name="root_audio" msgid="3505830755201326018">"ઑડિયો"</string>
+    <string name="root_videos" msgid="8792703517064649453">"વિડિઓઝ"</string>
+    <string name="root_audio" msgid="3505830755201326018">"ઑડિઓ"</string>
     <string name="root_documents" msgid="3829103301363849237">"દસ્તાવેજો"</string>
     <string name="permission_required" msgid="1460820436132943754">"આ આઇટમમાં ફેરફાર કરવા માટે અથવા તેને ડિલીટ કરવા માટે પરવાનગી હોવી જરૂરી છે."</string>
     <string name="permission_required_action" msgid="706370952366113539">"આગળ વધો"</string>
@@ -37,10 +37,8 @@
       <item quantity="one">ઉપરાંત <xliff:g id="COUNT_1">^1</xliff:g> વધારાની આઇટમ</item>
       <item quantity="other">ઉપરાંત <xliff:g id="COUNT_1">^1</xliff:g> વધારાની આઇટમ</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ઍપની બધી અસ્થાયી ફાઇલ સાફ કરો"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ઍપની બધી અસ્થાયી ફાઇલોને સાફ કરીએ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> કેટલીક અસ્થાયી ફાઇલોને સાફ કરવા માગે છે. આના પરિણામે બૅટરી અથવા સેલ્યુલર ડેટાના વપરાશમાં વધારો થઈ શકે છે."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ઍપની બધી અસ્થાયી ફાઇલો સાફ કરી રહ્યાં છીએ…"</string>
-    <string name="clear" msgid="5524638938415865915">"સાફ કરો"</string>
     <string name="allow" msgid="8885707816848569619">"મંજૂરી આપો"</string>
     <string name="deny" msgid="6040983710442068936">"નકારો"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 3937bd2..345cbf8 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -21,7 +21,7 @@
     <string name="app_label" msgid="9035307001052716210">"मीडिया मेमोरी"</string>
     <string name="artist_label" msgid="8105600993099120273">"कलाकार"</string>
     <string name="unknown" msgid="2059049215682829375">"अज्ञात"</string>
-    <string name="root_images" msgid="5861633549189045666">"इमेज"</string>
+    <string name="root_images" msgid="5861633549189045666">"चित्र"</string>
     <string name="root_videos" msgid="8792703517064649453">"वीडियो"</string>
     <string name="root_audio" msgid="3505830755201326018">"ऑडियो"</string>
     <string name="root_documents" msgid="3829103301363849237">"दस्तावेज़"</string>
@@ -37,14 +37,12 @@
       <item quantity="one">अन्य <xliff:g id="COUNT_1">^1</xliff:g> आइटम</item>
       <item quantity="other">अन्य <xliff:g id="COUNT_1">^1</xliff:g> आइटम</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ऐप्लिकेशन से जुड़ी, कुछ समय तक सेव रहने वाली फ़ाइलें मिटाएं"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ऐप्लिकेशन से जुड़ी, कुछ समय तक रहने वाली फ़ाइलें मिटाना चाहते हैं?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> कुछ समय तक रहने वाली फ़ाइलें हटाना चाहता है. इससे बैटरी या मोबाइल डेटा का इस्तेमाल बढ़ सकता है."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ऐप्लिकेशन से जुड़ी, कुछ समय तक सेव रहने वाली फ़ाइलें मिटाई जा रही हैं…"</string>
-    <string name="clear" msgid="5524638938415865915">"मिटाएं"</string>
     <string name="allow" msgid="8885707816848569619">"अनुमति दें"</string>
     <string name="deny" msgid="6040983710442068936">"अनुमति न दें"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
-      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइल में बदलाव करने की अनुमति देना चाहते हैं?</item>
+      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलों में बदलाव करने की अनुमति देना चाहते हैं?</item>
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलों में बदलाव करने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_write_video" formatted="false" msgid="1098082003326873084">
@@ -60,7 +58,7 @@
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> आइटम में बदलाव करने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_trash_audio" formatted="false" msgid="8907813869381755423">
-      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइल, ट्रैश में मूव करने की अनुमति देना चाहते हैं?</item>
+      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलें, ट्रैश में मूव करने की अनुमति देना चाहते हैं?</item>
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलें, ट्रैश में मूव करने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_trash_video" formatted="false" msgid="4672871911555787438">
@@ -76,7 +74,7 @@
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> आइटम, ट्रैश में मूव करने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_untrash_audio" formatted="false" msgid="7795265980168966321">
-      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइल, ट्रैश से बाहर निकालने की अनुमति देना चाहते हैं?</item>
+      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलें, ट्रैश से बाहर निकालने की अनुमति देना चाहते हैं?</item>
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलें, ट्रैश से बाहर निकालने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_untrash_video" formatted="false" msgid="332894888445508879">
@@ -92,7 +90,7 @@
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> आइटम, ट्रैश से बाहर निकालने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_delete_audio" formatted="false" msgid="6848547621165184719">
-      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइल मिटाने की अनुमति देना चाहते हैं?</item>
+      <item quantity="one">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलें मिटाने की अनुमति देना चाहते हैं?</item>
       <item quantity="other">क्या आप <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलें मिटाने की अनुमति देना चाहते हैं?</item>
     </plurals>
     <plurals name="permission_delete_video" formatted="false" msgid="1251942606336748563">
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 6b4abd9..3f07d2c 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -39,10 +39,8 @@
       <item quantity="few">Plus sljedeći broj dodatnih stavki: <xliff:g id="COUNT_1">^1</xliff:g></item>
       <item quantity="other">Plus sljedeći broj dodatnih stavki: <xliff:g id="COUNT_1">^1</xliff:g></item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Brisanje privremenih datoteka aplikacija"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Želite li izbrisati privremene datoteke aplikacija?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> želi izbrisati neke privremene datoteke. Zbog toga može doći do veće upotrebe baterije ili mobilnih podataka."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Brišu se privremene datoteke aplikacija…"</string>
-    <string name="clear" msgid="5524638938415865915">"Izbriši"</string>
     <string name="allow" msgid="8885707816848569619">"Dopusti"</string>
     <string name="deny" msgid="6040983710442068936">"Odbij"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 1e39499..6e39b1a 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">És további <xliff:g id="COUNT_1">^1</xliff:g> elem</item>
       <item quantity="one">És további <xliff:g id="COUNT_0">^1</xliff:g> elem</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ideiglenes alkalmazásfájlok törlése"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Törli az ideiglenes alkalmazásfájlokat?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"A(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> szeretne törölni néhány ideiglenes fájlt. Ez nagyobb akkumulátor- és mobiladat-használatot eredményezhet."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Ideiglenes alkalmazásfájlok törlése…"</string>
-    <string name="clear" msgid="5524638938415865915">"Törlés"</string>
     <string name="allow" msgid="8885707816848569619">"Engedélyezés"</string>
     <string name="deny" msgid="6040983710442068936">"Tiltás"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 862e27a..1fceb95 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Ու ևս <xliff:g id="COUNT_1">^1</xliff:g> լրացուցիչ տարր</item>
       <item quantity="other">Ու ևս <xliff:g id="COUNT_1">^1</xliff:g> լրացուցիչ տարր</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ջնջեք հավելվածի լրացուցիչ ֆայլերը"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Ջնջե՞լ հավելվածի լրացուցիչ ֆայլերը"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածը հայցում է որոշ ժամանակավոր ֆայլեր ջնջելու թույլտվություն։ Դրա համար կարող է օգտագործվել ավելի շատ մարտկոցի լիցք կամ բջջային ինտերնետ։"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Հավելվածների ժամանակավոր ֆայլերը ջնջվում են…"</string>
-    <string name="clear" msgid="5524638938415865915">"Ջնջել"</string>
     <string name="allow" msgid="8885707816848569619">"Թույլատրել"</string>
     <string name="deny" msgid="6040983710442068936">"Մերժել"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 42406d7..4ac8d71 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> item tambahan</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> item tambahan</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Menghapus file aplikasi sementara"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Hapus file aplikasi sementara?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ingin menghapus beberapa file sementara. Ini dapat meningkatkan penggunaan baterai atau data seluler."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Menghapus file aplikasi sementara…"</string>
-    <string name="clear" msgid="5524638938415865915">"Hapus"</string>
     <string name="allow" msgid="8885707816848569619">"Izinkan"</string>
     <string name="deny" msgid="6040983710442068936">"Tolak"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index fb7daa3..f389881 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Auk <xliff:g id="COUNT_1">^1</xliff:g> atriðis til viðbótar</item>
       <item quantity="other">Auk <xliff:g id="COUNT_1">^1</xliff:g> atriða til viðbótar</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Hreinsa tímabundnar forritaskrár"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Hreinsa tímabundnar forritaskrár?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vill fá að hreinsa sumar tímabundnar skrár. Þetta getur haft í för með sér aukna rafhlöðunotkun eða notkun farsímagagna."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Verið er að eyða tímabundnum forritaskrám…"</string>
-    <string name="clear" msgid="5524638938415865915">"Hreinsa"</string>
     <string name="allow" msgid="8885707816848569619">"Leyfa"</string>
     <string name="deny" msgid="6040983710442068936">"Hafna"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 9b5d598..100921d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Più altri <xliff:g id="COUNT_1">^1</xliff:g> elementi</item>
       <item quantity="one">Più <xliff:g id="COUNT_0">^1</xliff:g> altro elemento</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Cancellare file temporanei delle app"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Cancellare i file temporanei delle app?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"L\'app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vorrebbe cancellare alcuni file temporanei. In tal caso potrebbe verificarsi un maggiore utilizzo della batteria o della rete dati."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Cancellazione dei file temporanei delle app…"</string>
-    <string name="clear" msgid="5524638938415865915">"Cancella"</string>
     <string name="allow" msgid="8885707816848569619">"Consenti"</string>
     <string name="deny" msgid="6040983710442068936">"Rifiuta"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 24f2c3a..d4d0107 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="other">ועוד <xliff:g id="COUNT_1">^1</xliff:g> פריטים נוספים</item>
       <item quantity="one">ועוד פריט אחד נוסף (<xliff:g id="COUNT_0">^1</xliff:g>)</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ניקוי קובצי אפליקציה זמניים"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"לנקות קובצי אפליקציה זמניים?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"קיבלת בקשה מהאפליקציה <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> לניקוי של חלק מהקבצים הזמניים. הפעולה עשויה להגביר את השימוש בסוללה או בחבילת הגלישה."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"מתבצע ניקוי של קובצי אפליקציה זמניים…"</string>
-    <string name="clear" msgid="5524638938415865915">"ניקוי"</string>
     <string name="allow" msgid="8885707816848569619">"אישור"</string>
     <string name="deny" msgid="6040983710442068936">"דחייה"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index a7795b9..8f13004 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">他 <xliff:g id="COUNT_1">^1</xliff:g> 件の項目</item>
       <item quantity="one">他 <xliff:g id="COUNT_0">^1</xliff:g> 件の項目</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"アプリの一時ファイルの削除"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"アプリの一時ファイルを削除しますか?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>が一部の一時ファイルを削除する権限を求めています。この処理により、電池やモバイルデータの使用量が増えることがあります。"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"アプリの一時ファイルを削除しています…"</string>
-    <string name="clear" msgid="5524638938415865915">"削除"</string>
     <string name="allow" msgid="8885707816848569619">"許可"</string>
     <string name="deny" msgid="6040983710442068936">"許可しない"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 420e846..5a77cda 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">და კიდევ <xliff:g id="COUNT_1">^1</xliff:g> დამატებითი ერთეული</item>
       <item quantity="one">და კიდევ <xliff:g id="COUNT_0">^1</xliff:g> დამატებითი ერთეული</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"გასუფთავდეს აპის დროებითი ფაილები?"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"გასუფთავდეს აპის დროებითი ფაილები?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ს სურს, გაასუფთაოს დროებითი ფაილები. ამან შეიძლება ზოგიერთი ბატარეის ან მობილური ინტერნეტის გაზრდილი მოხმარება გამოიწვიოს."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"მიმდინარეობს აპის დროებითი ფაილების გასუფთავება…"</string>
-    <string name="clear" msgid="5524638938415865915">"გასუფთავება"</string>
     <string name="allow" msgid="8885707816848569619">"დაშვება"</string>
     <string name="deny" msgid="6040983710442068936">"უარყოფა"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 1b899b2..efe23b2 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Тағы <xliff:g id="COUNT_1">^1</xliff:g> элемент</item>
       <item quantity="one">Тағы <xliff:g id="COUNT_0">^1</xliff:g> элемент</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Қолданбаның уақытша файлдарын өшіру"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Қолданбаның уақытша файлдарын өшіру керек пе?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> кейбір уақытша файлдарды өшіргісі келеді. Соған байланысты батарея тез отыруы немесе мобильдік интернет трафигі көп кетуі мүмкін."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Қолданбаның уақытша файлдары өшірілуде…"</string>
-    <string name="clear" msgid="5524638938415865915">"Өшіру"</string>
     <string name="allow" msgid="8885707816848569619">"Рұқсат ету"</string>
     <string name="deny" msgid="6040983710442068936">"Тыйым салу"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index b4a930f..dbc2e18 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">បូករួម​ទាំង​ធាតុ <xliff:g id="COUNT_1">^1</xliff:g> បន្ថែម​ទៀត</item>
       <item quantity="one">បូករួម​ទាំង​ធាតុ <xliff:g id="COUNT_0">^1</xliff:g> បន្ថែម​ទៀត</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"សម្អាត​ឯកសារ​កម្មវិធី​បណ្ដោះអាសន្ន"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"សម្អាត​ឯកសារ​កម្មវិធី​បណ្ដោះអាសន្ន​ឬ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ចង់​សម្អាត​ឯកសារ​បណ្ដោះអាសន្ន​មួយចំនួន។ សកម្មភាពនេះ​អាច​បណ្ដាលឱ្យ​ការប្រើប្រាស់​ថ្ម ឬ​ទិន្នន័យ​ទូរសព្ទចល័ត​មានការកើនឡើង​។"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"កំពុងសម្អាត​ឯកសារ​កម្មវិធី​បណ្ដោះអាសន្ន…"</string>
-    <string name="clear" msgid="5524638938415865915">"សម្អាត"</string>
     <string name="allow" msgid="8885707816848569619">"អនុញ្ញាត"</string>
     <string name="deny" msgid="6040983710442068936">"បដិសេធ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index a39e574..45bde30 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">ಜೊತೆಗೆ <xliff:g id="COUNT_1">^1</xliff:g> ಹೆಚ್ಚುವರಿ ಐಟಂಗಳು</item>
       <item quantity="other">ಜೊತೆಗೆ <xliff:g id="COUNT_1">^1</xliff:g> ಹೆಚ್ಚುವರಿ ಐಟಂಗಳು</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ತಾತ್ಕಾಲಿಕ ಆ್ಯಪ್ ಫೈಲ್‌ಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ತಾತ್ಕಾಲಿಕ ಆ್ಯಪ್ ಫೈಲ್‌ಗಳನ್ನು ತೆರವುಗೊಳಿಸಬೇಕೇ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ಕೆಲವು ತಾತ್ಕಾಲಿಕ ಫೈಲ್‌ಗಳನ್ನು ತೆರವುಗೊಳಿಸಲು ಬಯಸುತ್ತಿದೆ. ಬ್ಯಾಟರಿ ಅಥವಾ ಸೆಲ್ಯುಲರ್ ಡೇಟಾ ಹೆಚ್ಚು ಬಳಕೆಯಾಗಲು ಇದು ಕಾರಣವಾಗಬಹುದು."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ತಾತ್ಕಾಲಿಕ ಆ್ಯಪ್ ಫೈಲ್‌ಗಳನ್ನು ತೆರವುಗೊಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="clear" msgid="5524638938415865915">"ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="allow" msgid="8885707816848569619">"ಅನುಮತಿಸಿ"</string>
     <string name="deny" msgid="6040983710442068936">"ನಿರಾಕರಿಸಿ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 97fa4ec..c6ed4a1 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">그 외 항목 <xliff:g id="COUNT_1">^1</xliff:g>개</item>
       <item quantity="one">그 외 항목 <xliff:g id="COUNT_0">^1</xliff:g>개</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"임시 앱 파일 삭제"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"임시 앱 파일을 삭제하시겠습니까?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 일부 임시 파일을 삭제하려고 합니다. 이로 인해 배터리 또는 모바일 데이터 사용량이 늘어날 수 있습니다."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"임시 앱 파일 삭제 중…"</string>
-    <string name="clear" msgid="5524638938415865915">"삭제"</string>
     <string name="allow" msgid="8885707816848569619">"허용"</string>
     <string name="deny" msgid="6040983710442068936">"거부"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 6198dba..5b6881c 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Дагы <xliff:g id="COUNT_1">^1</xliff:g> нерсе</item>
       <item quantity="one">Дагы <xliff:g id="COUNT_0">^1</xliff:g> нерсе</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Колдонмодогу убактылуу файлдарды өчүрүү"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Колдонмодогу убактылуу файлдарды өчүрөсүзбү?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> айрым убактылуу файлдарды өчүргөнү жатат. Батарея же мобилдик Интернет өтө көп колдонулушу мүмкүн."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Колдонмодогу убактылуу файлдар өчүрүлүүдө…"</string>
-    <string name="clear" msgid="5524638938415865915">"Тазалоо"</string>
     <string name="allow" msgid="8885707816848569619">"Уруксат берүү"</string>
     <string name="deny" msgid="6040983710442068936">"Тыюу салуу"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 568d20a..4e490fd 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">ຮວມ <xliff:g id="COUNT_1">^1</xliff:g> ລາຍການເພີ່ມເຕີມ</item>
       <item quantity="one">ຮວມ <xliff:g id="COUNT_0">^1</xliff:g> ລາຍການເພີ່ມເຕີມ</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ລຶບລ້າງໄຟລ໌ແອັບຊົ່ວຄາວ"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ລຶບລ້າງໄຟລ໌ແອັບຊົ່ວຄາວບໍ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ຕ້ອງການລ້າງໄຟລ໌ຊົ່ວຄາວບາງຢ່າງອອກ. ນີ້ອາດເຮັດໃຫ້ມີການໃຊ້ແບັດເຕີຣີ ຫຼື ອິນເຕີເນັດມືຖືຫຼາຍຂຶ້ນ."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ກຳລັງລຶບລ້າງໄຟລ໌ແອັບຊົ່ວຄາວ…"</string>
-    <string name="clear" msgid="5524638938415865915">"ລຶບລ້າງ"</string>
     <string name="allow" msgid="8885707816848569619">"ອະນຸຍາດ"</string>
     <string name="deny" msgid="6040983710442068936">"ປະຕິເສດ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 4190c0f..8adcbab 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="many">Dar <xliff:g id="COUNT_1">^1</xliff:g> papildomo elemento</item>
       <item quantity="other">Dar <xliff:g id="COUNT_1">^1</xliff:g> papildomų elementų</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Laikinų programų failų išvalymas"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Išvalyti laikinus programų failus?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Programa „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ nori išvalyti kai kuriuos laikinus failus. Dėl to gali būti suvartojama daugiau akumuliatoriaus energijos ar mobiliojo ryšio duomenų."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Išvalomi laikini programos failai…"</string>
-    <string name="clear" msgid="5524638938415865915">"Išvalyti"</string>
     <string name="allow" msgid="8885707816848569619">"Leisti"</string>
     <string name="deny" msgid="6040983710442068936">"Atmesti"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 7bc296f..f12414b 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -39,10 +39,8 @@
       <item quantity="one">Un vēl <xliff:g id="COUNT_1">^1</xliff:g> vienums</item>
       <item quantity="other">Un vēl <xliff:g id="COUNT_1">^1</xliff:g> vienumi</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Lietotņu pagaidu failu notīrīšana"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vai notīrīt lietotņu pagaidu failus?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Lietotne <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vēlas iegūt atļauju notīrīt dažus pagaidu failus. Tas var palielināt akumulatora izmantošanas ilgumu vai mobilo datu lietojumu."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Notiek lietotņu pagaidu failu notīrīšana…"</string>
-    <string name="clear" msgid="5524638938415865915">"Notīrīt"</string>
     <string name="allow" msgid="8885707816848569619">"Atļaut"</string>
     <string name="deny" msgid="6040983710442068936">"Neatļaut"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 9dd0bf3..b136efb 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Плус <xliff:g id="COUNT_1">^1</xliff:g> дополнителна ставка</item>
       <item quantity="other">Плус <xliff:g id="COUNT_1">^1</xliff:g> дополнителни ставки</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Избриши ги привремените датотеки на апликацијата"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Да се избришат привремените датотеки на апликацијата?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> сака да избрише некои привремени датотеки. Поради тоа може да дојде до зголемено користење на батеријата или мобилниот интернет."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Се бришат привремените датотеки на апликацијата…"</string>
-    <string name="clear" msgid="5524638938415865915">"Избриши"</string>
     <string name="allow" msgid="8885707816848569619">"Дозволи"</string>
     <string name="deny" msgid="6040983710442068936">"Одбиј"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 05d8624..a556f66 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other"><xliff:g id="COUNT_1">^1</xliff:g> അധിക ഇനങ്ങൾ കൂടി</item>
       <item quantity="one"><xliff:g id="COUNT_0">^1</xliff:g> അധിക ഇനം കൂടി</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"താൽക്കാലികമായ ആപ്പ് ഫയലുകൾ മായ്ക്കുക"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"താൽക്കാലികമായ ആപ്പ് ഫയലുകൾ മായ്ക്കണോ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് കുറച്ച് താൽക്കാലിക ഫയലുകൾ മായ്ക്കണമെന്നുണ്ട്. ബാറ്ററിയുടെയോ സെല്ലുലാർ ഡാറ്റയുടെയോ വർദ്ധിച്ച ഉപയോഗത്തിന് ഇത് കാരണമായേക്കാം."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"താൽക്കാലികമായ ആപ്പ് ഫയലുകൾ മായ്‌ക്കുന്നു…"</string>
-    <string name="clear" msgid="5524638938415865915">"മായ്ക്കുക"</string>
     <string name="allow" msgid="8885707816848569619">"അനുവദിക്കൂ"</string>
     <string name="deny" msgid="6040983710442068936">"നിരസിക്കുക"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 8c7a39b..0e5dc0d 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Нэмээд нэмэлт <xliff:g id="COUNT_1">^1</xliff:g> зүйл</item>
       <item quantity="one">Нэмээд нэмэлт <xliff:g id="COUNT_0">^1</xliff:g> зүйл</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Аппын түр зуурын файлуудыг арилгах"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Аппын түр зуурын файлуудыг арилгах уу?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> нь түр зуурын зарим файлыг арилгах хүсэлтэй байна. Энэ нь батарей эсвэл мобайл дата ашиглалтыг нэмэгдүүлэхэд хүргэж болзошгүй."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Аппын түр зуурын файлуудыг арилгаж байна…"</string>
-    <string name="clear" msgid="5524638938415865915">"Арилгах"</string>
     <string name="allow" msgid="8885707816848569619">"Зөвшөөрөх"</string>
     <string name="deny" msgid="6040983710442068936">"Татгалзах"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 9a6b24e..331ee53 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">आणखी <xliff:g id="COUNT_1">^1</xliff:g> अतिरिक्त आयटम</item>
       <item quantity="one">आणखी <xliff:g id="COUNT_0">^1</xliff:g> अतिरिक्त आयटम</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"तात्पुरत्या अ‍ॅप फाइल साफ करा"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"तात्पुरत्या अ‍ॅप फाइल काढून टाकायच्या आहेत का?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला काही तात्पुरत्या फाइल साफ करायच्या आहेत. यामुळे बॅटरी किंवा सेल्युलर डेटाच्या वापरात वाढ होऊ शकते."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"तात्‍पुरत्‍या ॲप फाइल काढून टाकत आहे…"</string>
-    <string name="clear" msgid="5524638938415865915">"साफ करा"</string>
     <string name="allow" msgid="8885707816848569619">"अनुमती द्या"</string>
     <string name="deny" msgid="6040983710442068936">"नकार द्या"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 067cc43..6846e67 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Serta <xliff:g id="COUNT_1">^1</xliff:g> item tambahan</item>
       <item quantity="one">Serta <xliff:g id="COUNT_0">^1</xliff:g> item tambahan</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Kosongkan fail apl sementara"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Kosongkan fail apl sementara?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> mahu mengosongkan beberapa fail sementara. Tindakan ini mungkin menyebabkan peningkatan penggunaan bateri atau data selular."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Mengosongkan fail apl sementara…"</string>
-    <string name="clear" msgid="5524638938415865915">"Kosongkan"</string>
     <string name="allow" msgid="8885707816848569619">"Benarkan"</string>
     <string name="deny" msgid="6040983710442068936">"Tolak"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index ab3766c..a10071e 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">ထပ်ပေါင်းအရာ <xliff:g id="COUNT_1">^1</xliff:g> ခု အပါအဝင်</item>
       <item quantity="one">ထပ်ပေါင်းအရာ <xliff:g id="COUNT_0">^1</xliff:g> ခု အပါအဝင်</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ယာယီအက်ပ်ဖိုင်များ ရှင်းရန်"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ယာယီအက်ပ်ဖိုင်များ ရှင်းထုတ်မလား။"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် ယာယီဖိုင်များမှ အချို့ကို ရှင်းထုတ်လိုသည်။ ထို့ကြောင့် ဘက်ထရီ သို့မဟုတ် ဆယ်လူလာဒေတာ အသုံးပြုမှု မြင့်တက်လာနိုင်သည်။"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ယာယီအက်ပ်ဖိုင်များ ရှင်းထုတ်နေသည်…"</string>
-    <string name="clear" msgid="5524638938415865915">"ရှင်းရန်"</string>
     <string name="allow" msgid="8885707816848569619">"ခွင့်ပြုရန်"</string>
     <string name="deny" msgid="6040983710442068936">"ပယ်ရန်"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 35fd892..d3b049d 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Pluss <xliff:g id="COUNT_1">^1</xliff:g> elementer til</item>
       <item quantity="one">Pluss <xliff:g id="COUNT_0">^1</xliff:g> element til</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Slett midlertidige appfiler"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vil du slette midlertidige appfiler?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vil slette noen midlertidige filer. Dette kan resultere i økt bruk av batteri eller mobildata."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Sletter midlertidige appfiler …"</string>
-    <string name="clear" msgid="5524638938415865915">"Slett"</string>
     <string name="allow" msgid="8885707816848569619">"Tillat"</string>
     <string name="deny" msgid="6040983710442068936">"Avvis"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 0735ae7..9658899 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">थप <xliff:g id="COUNT_1">^1</xliff:g> वटा अतिरिक्त वस्तु</item>
       <item quantity="one">थप <xliff:g id="COUNT_0">^1</xliff:g> अतिरिक्त वस्तु</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"एपका अस्थायी फाइलहरू हटाउनुहोस्"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"अनुप्रयोगका अस्थायी फाइलहरू मेटाउने हो?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> केही अस्थायी फाइलहरू मेटाउन चाहन्छ। यो कार्य गर्ने अनुमति दिनुभएका खण्डमा ब्याट्रीको खपत वा सेलुलर डेटाको प्रयोग बढ्न सक्छ।"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"एपका अस्थायी फाइलहरू मेटाउँदै…"</string>
-    <string name="clear" msgid="5524638938415865915">"हटाउनुहोस्"</string>
     <string name="allow" msgid="8885707816848569619">"अनुमति दिनुहोस्"</string>
     <string name="deny" msgid="6040983710442068936">"अस्वीकार गर्नुहोस्"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
@@ -52,8 +50,8 @@
       <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो भिडियो परिमार्जन गर्न दिने हो?</item>
     </plurals>
     <plurals name="permission_write_image" formatted="false" msgid="748745548893845892">
-      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> फोटोहरू परिमार्जन गर्न दिने हो?</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो फोटो परिमार्जन गर्न दिने हो?</item>
+      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> तस्बिरहरू परिमार्जन गर्न दिने हो?</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो तस्बिर परिमार्जन गर्न दिने हो?</item>
     </plurals>
     <plurals name="permission_write_generic" formatted="false" msgid="3270172714743671779">
       <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> वस्तुहरू परिमार्जन गर्न दिने हो?</item>
@@ -68,8 +66,8 @@
       <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो भिडियो सारेर रद्दीको टोकरीमा लैजान दिने हो?</item>
     </plurals>
     <plurals name="permission_trash_image" formatted="false" msgid="6400475304599873227">
-      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> फोटोहरू सारेर रद्दीको टोकरीमा लैजान दिने हो?</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो फोटो सारेर रद्दीको टोकरीमा लैजान दिने हो?</item>
+      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> तस्बिरहरू सारेर रद्दीको टोकरीमा लैजान दिने हो?</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो तस्बिर सारेर रद्दीको टोकरीमा लैजान दिने हो?</item>
     </plurals>
     <plurals name="permission_trash_generic" formatted="false" msgid="3814167365075039711">
       <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> वस्तुहरू सारेर रद्दीको टोकरीमा लैजान दिने हो?</item>
@@ -84,8 +82,8 @@
       <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो भिडियो रद्दीको टोकरीबाट निकालेर ल्याउन दिने हो?</item>
     </plurals>
     <plurals name="permission_untrash_image" formatted="false" msgid="7024071378733595056">
-      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> फोटोहरू रद्दीको टोकरीबाट निकालेर ल्याउन दिने हो?</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो फोटो रद्दीको टोकरीबाट निकालेर ल्याउन दिने हो?</item>
+      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> तस्बिरहरू रद्दीको टोकरीबाट निकालेर ल्याउन दिने हो?</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो तस्बिर रद्दीको टोकरीबाट निकालेर ल्याउन दिने हो?</item>
     </plurals>
     <plurals name="permission_untrash_generic" formatted="false" msgid="6872817093731198374">
       <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> वस्तुहरू रद्दीको टोकरीबाट निकालेर ल्याउन दिने हो?</item>
@@ -100,8 +98,8 @@
       <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो भिडियो मेटाउन दिने हो?</item>
     </plurals>
     <plurals name="permission_delete_image" formatted="false" msgid="2303409455224710111">
-      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> फोटोहरू मेटाउन दिने हो?</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो फोटो मेटाउन दिने हो?</item>
+      <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> तस्बिरहरू मेटाउन दिने हो?</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो तस्बिर मेटाउन दिने हो?</item>
     </plurals>
     <plurals name="permission_delete_generic" formatted="false" msgid="1412218850351841181">
       <item quantity="other"><xliff:g id="APP_NAME_1">^1</xliff:g> लाई यी <xliff:g id="COUNT">^2</xliff:g> वस्तुहरू मेटाउन दिने हो?</item>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index d685675..69e344b 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -25,7 +25,7 @@
     <string name="root_videos" msgid="8792703517064649453">"Video\'s"</string>
     <string name="root_audio" msgid="3505830755201326018">"Audio"</string>
     <string name="root_documents" msgid="3829103301363849237">"Documenten"</string>
-    <string name="permission_required" msgid="1460820436132943754">"Rechten vereist om dit item aan te passen of te verwijderen."</string>
+    <string name="permission_required" msgid="1460820436132943754">"Toestemming vereist om dit item aan te passen of te verwijderen."</string>
     <string name="permission_required_action" msgid="706370952366113539">"Doorgaan"</string>
     <string name="grant_dialog_button_allow" msgid="1644287024501033471">"Toestaan"</string>
     <string name="grant_dialog_button_deny" msgid="6190589471415815741">"Weigeren"</string>
@@ -37,10 +37,8 @@
       <item quantity="other">Plus <xliff:g id="COUNT_1">^1</xliff:g> extra items</item>
       <item quantity="one">Plus <xliff:g id="COUNT_0">^1</xliff:g> extra item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Tijdelijke app-bestanden wissen"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Tijdelijke app-bestanden wissen?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> wil een aantal tijdelijke bestanden wissen. Dit kan leiden tot een groter verbruik van de batterij of mobiele data."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Tijdelijke app-bestanden wissen…"</string>
-    <string name="clear" msgid="5524638938415865915">"Wissen"</string>
     <string name="allow" msgid="8885707816848569619">"Toestaan"</string>
     <string name="deny" msgid="6040983710442068936">"Weigeren"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 86491af..ea938eb 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -28,7 +28,7 @@
     <string name="permission_required" msgid="1460820436132943754">"ଏହି ଆଇଟମ୍‌କୁ ସଂଶୋଧନ କିମ୍ବା ଡିଲିଟ୍‌ କରିବାକୁ ଅନୁମତି ଆବଶ୍ୟକ।"</string>
     <string name="permission_required_action" msgid="706370952366113539">"ଜାରି ରଖନ୍ତୁ"</string>
     <string name="grant_dialog_button_allow" msgid="1644287024501033471">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
-    <string name="grant_dialog_button_deny" msgid="6190589471415815741">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
+    <string name="grant_dialog_button_deny" msgid="6190589471415815741">"ଅସ୍ଵୀକାର କରନ୍ତୁ"</string>
     <plurals name="permission_more_thumb" formatted="false" msgid="4392079224649478923">
       <item quantity="other">+<xliff:g id="COUNT_1">^1</xliff:g></item>
       <item quantity="one">+<xliff:g id="COUNT_0">^1</xliff:g></item>
@@ -37,12 +37,10 @@
       <item quantity="other">ଅଧିକ <xliff:g id="COUNT_1">^1</xliff:g>ଟି ଅତିରିକ୍ତ ଆଇଟମ୍</item>
       <item quantity="one">ଅଧିକ <xliff:g id="COUNT_0">^1</xliff:g>ଟି ଅତିରିକ୍ତ ଆଇଟମ୍</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ଅସ୍ଥାୟୀ ଆପ୍ ଫାଇଲଗୁଡ଼ିକୁ ଖାଲି କରନ୍ତୁ"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ଅସ୍ଥାୟୀ ଆପ୍ ଫାଇଲଗୁଡ଼ିକୁ ଖାଲି କରିବେ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> କିଛି ଅସ୍ଥାୟୀ ଫାଇଲ୍ ଖାଲି କରିବାକୁ ଚାହୁଁଛି। ଏହା ଫଳରେ ବ୍ୟାଟେରୀ କିମ୍ବା ସେଲ୍ୟୁଲାର୍ ଡାଟାର ବ୍ୟବହାର ଅଧିକ ହୋଇପାରେ।"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ଅସ୍ଥାୟୀ ଆପ୍ ଫାଇଲଗୁଡ଼ିକୁ ଖାଲି କରାଯାଉଛି…"</string>
-    <string name="clear" msgid="5524638938415865915">"ଖାଲି କରନ୍ତୁ"</string>
     <string name="allow" msgid="8885707816848569619">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
-    <string name="deny" msgid="6040983710442068936">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
+    <string name="deny" msgid="6040983710442068936">"ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତୁ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
       <item quantity="other"><xliff:g id="COUNT">^2</xliff:g>ଟି ଅଡିଓ ଫାଇଲକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ <xliff:g id="APP_NAME_1">^1</xliff:g>କୁ ଅନୁମତି ଦେବେ?</item>
       <item quantity="one">ଏହି ଅଡିଓ ଫାଇଲକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ <xliff:g id="APP_NAME_0">^1</xliff:g>କୁ ଅନୁମତି ଦେବେ?</item>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index cb5e9b4..1efefcd 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -21,7 +21,7 @@
     <string name="app_label" msgid="9035307001052716210">"ਮੀਡੀਆ ਸਟੋਰੇਜ"</string>
     <string name="artist_label" msgid="8105600993099120273">"ਕਲਾਕਾਰ"</string>
     <string name="unknown" msgid="2059049215682829375">"ਅਗਿਆਤ"</string>
-    <string name="root_images" msgid="5861633549189045666">"ਚਿੱਤਰ"</string>
+    <string name="root_images" msgid="5861633549189045666">"ਚਿਤਰ"</string>
     <string name="root_videos" msgid="8792703517064649453">"ਵੀਡੀਓ"</string>
     <string name="root_audio" msgid="3505830755201326018">" ਆਡੀਓ"</string>
     <string name="root_documents" msgid="3829103301363849237">"ਦਸਤਾਵੇਜ਼"</string>
@@ -37,10 +37,8 @@
       <item quantity="one">ਇਸ ਤੋਂ ਇਲਾਵਾ <xliff:g id="COUNT_1">^1</xliff:g> ਵਾਧੂ ਆਈਟਮ</item>
       <item quantity="other">ਇਸ ਤੋਂ ਇਲਾਵਾ <xliff:g id="COUNT_1">^1</xliff:g> ਵਾਧੂ ਆਈਟਮਾਂ</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ਅਸਥਾਈ ਐਪ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਲੀਅਰ ਕਰੋ"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ਕੀ ਅਸਥਾਈ ਐਪ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਲੀਅਰ ਕਰਨਾ ਹੈ?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਕੁਝ ਅਸਥਾਈ ਫ਼ਾਈਲਾਂ ਕਲੀਅਰ ਕਰਨਾ ਚਾਹੁੰਦੀ ਹੈ। ਇਸਦੇ ਨਤੀਜੇ ਵਜੋਂ ਬੈਟਰੀ ਜਾਂ ਸੈਲਿਊਲਰ ਡਾਟਾ ਦੀ ਵਰਤੋਂ ਵਧ ਸਕਦੀ ਹੈ।"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ਅਸਥਾਈ ਐਪ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਲੀਅਰ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="clear" msgid="5524638938415865915">"ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="allow" msgid="8885707816848569619">"ਆਗਿਆ ਦਿਓ"</string>
     <string name="deny" msgid="6040983710442068936">"ਮਨ੍ਹਾ ਕਰੋ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index ea4a8ce..09eac9f 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -21,7 +21,7 @@
     <string name="app_label" msgid="9035307001052716210">"Przechowywanie multimediów"</string>
     <string name="artist_label" msgid="8105600993099120273">"Wykonawca"</string>
     <string name="unknown" msgid="2059049215682829375">"Nieznany"</string>
-    <string name="root_images" msgid="5861633549189045666">"Obrazy"</string>
+    <string name="root_images" msgid="5861633549189045666">"Grafika"</string>
     <string name="root_videos" msgid="8792703517064649453">"Filmy"</string>
     <string name="root_audio" msgid="3505830755201326018">"Dźwięk"</string>
     <string name="root_documents" msgid="3829103301363849237">"Dokumenty"</string>
@@ -41,10 +41,8 @@
       <item quantity="other">I <xliff:g id="COUNT_1">^1</xliff:g> dodatkowego elementu</item>
       <item quantity="one">I <xliff:g id="COUNT_0">^1</xliff:g> dodatkowy element</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Usuwanie tymczasowych plików aplikacji"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Usunąć tymczasowe pliki aplikacji?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> chce usunąć niektóre pliki tymczasowe. Może to spowodować zwiększenie wykorzystania baterii lub komórkowej transmisji danych."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Usuwam tymczasowe pliki aplikacji…"</string>
-    <string name="clear" msgid="5524638938415865915">"Wyczyść"</string>
     <string name="allow" msgid="8885707816848569619">"Zezwól"</string>
     <string name="deny" msgid="6040983710442068936">"Odmów"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index d0ff6d6..47b3beb 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Mais <xliff:g id="COUNT_1">^1</xliff:g> item extra</item>
       <item quantity="other">Mais <xliff:g id="COUNT_1">^1</xliff:g> itens extras</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Limpar arquivos temporários de apps"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Limpar arquivos temporários de apps?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> quer apagar alguns arquivos temporários. Isso pode aumentar o uso de bateria ou de dados da rede celular."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Limpando arquivos temporários de apps…"</string>
-    <string name="clear" msgid="5524638938415865915">"Limpar"</string>
     <string name="allow" msgid="8885707816848569619">"Permitir"</string>
     <string name="deny" msgid="6040983710442068936">"Negar"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 27c1cb0..00c1c13 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -37,74 +37,72 @@
       <item quantity="other">E <xliff:g id="COUNT_1">^1</xliff:g> itens adicionais</item>
       <item quantity="one">E <xliff:g id="COUNT_0">^1</xliff:g> item adicional</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Limpe ficheiros de apps temporários"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Pretende limpar os ficheiros temporários da app?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"A app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> pretende limpar alguns ficheiros temporários. Isto pode resultar num aumento da utilização da bateria ou dos dados móveis."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"A limpar ficheiros temporários da app…"</string>
-    <string name="clear" msgid="5524638938415865915">"Limpar"</string>
     <string name="allow" msgid="8885707816848569619">"Permitir"</string>
     <string name="deny" msgid="6040983710442068936">"Recusar"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este ficheiro de áudio?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este ficheiro de áudio?</item>
     </plurals>
     <plurals name="permission_write_video" formatted="false" msgid="1098082003326873084">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este vídeo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este vídeo?</item>
     </plurals>
     <plurals name="permission_write_image" formatted="false" msgid="748745548893845892">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> fotos?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique esta foto?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> fotos?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique esta foto?</item>
     </plurals>
     <plurals name="permission_write_generic" formatted="false" msgid="3270172714743671779">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> itens?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este item?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> itens?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este item?</item>
     </plurals>
     <plurals name="permission_trash_audio" formatted="false" msgid="8907813869381755423">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio para o lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova este ficheiro de áudio para o lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio para o lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova este ficheiro de áudio para o lixo?</item>
     </plurals>
     <plurals name="permission_trash_video" formatted="false" msgid="4672871911555787438">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> vídeos para o lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova este vídeo para o lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> vídeos para o lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova este vídeo para o lixo?</item>
     </plurals>
     <plurals name="permission_trash_image" formatted="false" msgid="6400475304599873227">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> fotos para o lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova esta foto para o lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> fotos para o lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova esta foto para o lixo?</item>
     </plurals>
     <plurals name="permission_trash_generic" formatted="false" msgid="3814167365075039711">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> itens para o lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova este item para o lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> mova <xliff:g id="COUNT">^2</xliff:g> itens para o lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> mova este item para o lixo?</item>
     </plurals>
     <plurals name="permission_untrash_audio" formatted="false" msgid="7795265980168966321">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio do lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire este ficheiro de áudio do lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio do lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire este ficheiro de áudio do lixo?</item>
     </plurals>
     <plurals name="permission_untrash_video" formatted="false" msgid="332894888445508879">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> vídeos do lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire este vídeo do lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> vídeos do lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire este vídeo do lixo?</item>
     </plurals>
     <plurals name="permission_untrash_image" formatted="false" msgid="7024071378733595056">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> fotos do lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire esta foto do lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> fotos do lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire esta foto do lixo?</item>
     </plurals>
     <plurals name="permission_untrash_generic" formatted="false" msgid="6872817093731198374">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> itens do lixo?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire este item do lixo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> retire <xliff:g id="COUNT">^2</xliff:g> itens do lixo?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> retire este item do lixo?</item>
     </plurals>
     <plurals name="permission_delete_audio" formatted="false" msgid="6848547621165184719">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine este ficheiro de áudio?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine este ficheiro de áudio?</item>
     </plurals>
     <plurals name="permission_delete_video" formatted="false" msgid="1251942606336748563">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> vídeos?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine este vídeo?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> vídeos?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine este vídeo?</item>
     </plurals>
     <plurals name="permission_delete_image" formatted="false" msgid="2303409455224710111">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> fotos?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine esta foto?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> fotos?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine esta foto?</item>
     </plurals>
     <plurals name="permission_delete_generic" formatted="false" msgid="1412218850351841181">
-      <item quantity="other">Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> itens?</item>
-      <item quantity="one">Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine este item?</item>
+      <item quantity="other">Pretende permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> elimine <xliff:g id="COUNT">^2</xliff:g> itens?</item>
+      <item quantity="one">Pretende permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> elimine este item?</item>
     </plurals>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index d0ff6d6..47b3beb 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Mais <xliff:g id="COUNT_1">^1</xliff:g> item extra</item>
       <item quantity="other">Mais <xliff:g id="COUNT_1">^1</xliff:g> itens extras</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Limpar arquivos temporários de apps"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Limpar arquivos temporários de apps?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"O app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> quer apagar alguns arquivos temporários. Isso pode aumentar o uso de bateria ou de dados da rede celular."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Limpando arquivos temporários de apps…"</string>
-    <string name="clear" msgid="5524638938415865915">"Limpar"</string>
     <string name="allow" msgid="8885707816848569619">"Permitir"</string>
     <string name="deny" msgid="6040983710442068936">"Negar"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 8df20b8..9d6efda 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -39,10 +39,8 @@
       <item quantity="other">Și încă <xliff:g id="COUNT_1">^1</xliff:g> de elemente</item>
       <item quantity="one">Și încă <xliff:g id="COUNT_0">^1</xliff:g> element</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ștergeți fișierele temporare ale aplicațiilor"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Ștergeți fișierele temporare ale aplicațiilor?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vrea să șteargă fișiere temporare. Aceasta poate duce la creșterea gradului de utilizare a bateriei sau a datelor mobile."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Se șterg fișierele temporare ale aplicațiilor…"</string>
-    <string name="clear" msgid="5524638938415865915">"Ștergeți"</string>
     <string name="allow" msgid="8885707816848569619">"Permiteți"</string>
     <string name="deny" msgid="6040983710442068936">"Refuzați"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index d7a1aaa..3dd6f19 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="many">и ещё <xliff:g id="COUNT_1">^1</xliff:g> объектов</item>
       <item quantity="other">и ещё <xliff:g id="COUNT_1">^1</xliff:g> объекта</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Удалить временные файлы приложений"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Удалить временные файлы приложения?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Приложение \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" запрашивает разрешение на удаление временных файлов. Это может увеличить расход заряда или трафика."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Удаление временных файлов приложения…"</string>
-    <string name="clear" msgid="5524638938415865915">"Удалить"</string>
     <string name="allow" msgid="8885707816848569619">"Разрешить"</string>
     <string name="deny" msgid="6040983710442068936">"Запретить"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index ad22297..932e979 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">සහ අමතර අයිතම <xliff:g id="COUNT_1">^1</xliff:g></item>
       <item quantity="other">සහ අමතර අයිතම <xliff:g id="COUNT_1">^1</xliff:g></item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"තාවකාලික යෙදුම් ගොනු හිස් කරන්න"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"තාවකාලික යෙදුම් ගොනු හිස් කරන්නද?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> සමහර තාවකාලික ගොනු හිස් කිරීමට කැමතියි. මෙය බැටරි බලයේ හෝ සෙලියුලර් දත්තවල වැඩි භාවිතයකට හේතු විය හැකිය."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"තාවකාලික යෙදුම් ගොනු හිස් කරමින්…"</string>
-    <string name="clear" msgid="5524638938415865915">"හිස් කරන්න"</string>
     <string name="allow" msgid="8885707816848569619">"ඉඩ දෙන්න"</string>
     <string name="deny" msgid="6040983710442068936">"ප්‍රතික්ෂේප කරන්න"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 359ba24..fb343c2 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="other">A <xliff:g id="COUNT_1">^1</xliff:g> ďalších položiek</item>
       <item quantity="one">A <xliff:g id="COUNT_0">^1</xliff:g> ďalšia položka</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Vymazanie dočasných súborov aplikácií"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Chcete vymazať dočasné súbory aplikácie?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> chce vymazať niekoľko dočasných súborov. To môže viesť k vyššiemu využívaniu batérie alebo mobilných dát."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Odstraňujú sa dočasné súbory aplikácie…"</string>
-    <string name="clear" msgid="5524638938415865915">"Vymazať"</string>
     <string name="allow" msgid="8885707816848569619">"Povoliť"</string>
     <string name="deny" msgid="6040983710442068936">"Zamietnuť"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index ff63498..ec2ac11 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="few">In še <xliff:g id="COUNT_1">^1</xliff:g> dodatni elementi</item>
       <item quantity="other">In še <xliff:g id="COUNT_1">^1</xliff:g> dodatnih elementov</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Brisanje začasnih datotek aplikacij"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Želite izbrisati začasne datoteke aplikacij?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> želi izbrisati nekaj začasnih datotek. To lahko povzroči povečano porabo energije baterije ali povečan prenos podatkov v mobilnem omrežju."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Brisanje začasnih datotek aplikacij …"</string>
-    <string name="clear" msgid="5524638938415865915">"Počisti"</string>
     <string name="allow" msgid="8885707816848569619">"Dovoli"</string>
     <string name="deny" msgid="6040983710442068936">"Zavrni"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 1e90f35..b8e5714 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Dhe <xliff:g id="COUNT_1">^1</xliff:g> artikuj të tjerë</item>
       <item quantity="one">Dhe <xliff:g id="COUNT_0">^1</xliff:g> artikull tjetër</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Pastro skedarët e përkohshëm të aplikacioneve"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Të pastrohen skedarët e përkohshëm të aplikacioneve?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dëshiron të pastrojë disa skedarë të përkohshëm. Kjo mund të rezultojë në një rritje të përdorimit të baterisë ose të të dhënave celulare."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Skedarët e përkohshëm të aplikacioneve po pastrohen…"</string>
-    <string name="clear" msgid="5524638938415865915">"Pastro"</string>
     <string name="allow" msgid="8885707816848569619">"Lejo"</string>
     <string name="deny" msgid="6040983710442068936">"Refuzo"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 079f9aa..b6cf4dd 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -39,10 +39,8 @@
       <item quantity="few">И још <xliff:g id="COUNT_1">^1</xliff:g> ставке</item>
       <item quantity="other">И још <xliff:g id="COUNT_1">^1</xliff:g> ставки</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Обришите привремене датотеке апликација"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Желите ли да обришете привремене датотеке апликација?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> жели да обрише неке привремене датотеке. Ово може да доведе до повећане потрошње батерије или мобилних података."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Бришу се привремене датотеке апликација…"</string>
-    <string name="clear" msgid="5524638938415865915">"Обриши"</string>
     <string name="allow" msgid="8885707816848569619">"Дозволи"</string>
     <string name="deny" msgid="6040983710442068936">"Одбиј"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index b0b990c..51a5d6c 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -22,7 +22,7 @@
     <string name="artist_label" msgid="8105600993099120273">"Artist"</string>
     <string name="unknown" msgid="2059049215682829375">"Okänd"</string>
     <string name="root_images" msgid="5861633549189045666">"Bilder"</string>
-    <string name="root_videos" msgid="8792703517064649453">"Videor"</string>
+    <string name="root_videos" msgid="8792703517064649453">"Videoklipp"</string>
     <string name="root_audio" msgid="3505830755201326018">"Ljud"</string>
     <string name="root_documents" msgid="3829103301363849237">"Dokument"</string>
     <string name="permission_required" msgid="1460820436132943754">"Behörighet krävs för att ändra eller radera objektet."</string>
@@ -37,10 +37,8 @@
       <item quantity="other">och <xliff:g id="COUNT_1">^1</xliff:g> objekt till</item>
       <item quantity="one">och <xliff:g id="COUNT_0">^1</xliff:g> objekt till</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Rensa tillfälliga appfiler"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Vill du ta bort tillfälliga appfiler?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vill ta bort några tillfälliga filer. Det kan leda till ökad batteriförbrukning eller användning av mobildata."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Tillfälliga appfiler rensas …"</string>
-    <string name="clear" msgid="5524638938415865915">"Rensa"</string>
     <string name="allow" msgid="8885707816848569619">"Tillåt"</string>
     <string name="deny" msgid="6040983710442068936">"Neka"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 4917e30..f66d910 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Pamoja na vipengee <xliff:g id="COUNT_1">^1</xliff:g> zaidi</item>
       <item quantity="one">Pamoja na kipengee <xliff:g id="COUNT_0">^1</xliff:g> zaidi</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Futa faili za muda za programu"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Ungependa kufuta faili za muda za programu?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ingependa kufuta baadhi ya faili za muda. Huenda hii ikasababisha kuongezeka kwa matumizi ya betri au data ya mtandao wa simu."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Inafuta faili za muda za programu…"</string>
-    <string name="clear" msgid="5524638938415865915">"Futa"</string>
     <string name="allow" msgid="8885707816848569619">"Ruhusu"</string>
     <string name="deny" msgid="6040983710442068936">"Kataa"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index a98d701..8e3c9c7 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -29,82 +29,31 @@
     <string name="permission_required_action" msgid="706370952366113539">"தொடர்க"</string>
     <string name="grant_dialog_button_allow" msgid="1644287024501033471">"அனுமதி"</string>
     <string name="grant_dialog_button_deny" msgid="6190589471415815741">"நிராகரி"</string>
-    <plurals name="permission_more_thumb" formatted="false" msgid="4392079224649478923">
-      <item quantity="other">+<xliff:g id="COUNT_1">^1</xliff:g></item>
-      <item quantity="one">+<xliff:g id="COUNT_0">^1</xliff:g></item>
-    </plurals>
+    <!-- no translation found for permission_more_thumb (4392079224649478923) -->
     <plurals name="permission_more_text" formatted="false" msgid="7291997297174507324">
       <item quantity="other">அத்துடன் கூடுதலாக <xliff:g id="COUNT_1">^1</xliff:g></item>
       <item quantity="one">அத்துடன் கூடுதலாக <xliff:g id="COUNT_0">^1</xliff:g></item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ஆப்ஸின் தற்காலிக ஃபைல்களை அழித்தல்"</string>
-    <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"சில தற்காலிக ஃபைல்களை நீக்குவதற்கு <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> அனுமதி கேட்கின்றது. இதனால் பேட்டரி அல்லது மொபைல் டேட்டா பயன்பாடு அதிகரிக்கக்கூடும்."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ஆப்ஸிலுள்ள தற்காலிக ஃபைல்களை அழிக்கிறது…"</string>
-    <string name="clear" msgid="5524638938415865915">"அழி"</string>
+    <!-- no translation found for cache_clearing_dialog_title (4672878017407595782) -->
+    <skip />
+    <!-- no translation found for cache_clearing_dialog_text (7057784635111940957) -->
+    <skip />
     <string name="allow" msgid="8885707816848569619">"அனுமதி"</string>
     <string name="deny" msgid="6040983710442068936">"நிராகரி"</string>
-    <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஆடியோ ஃபைல்களில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஆடியோ ஃபைலில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_write_video" formatted="false" msgid="1098082003326873084">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> வீடியோக்களில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த வீடியோவில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_write_image" formatted="false" msgid="748745548893845892">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> படங்களில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்தப் படத்தில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_write_generic" formatted="false" msgid="3270172714743671779">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஃபைல்களில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஃபைலில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_trash_audio" formatted="false" msgid="8907813869381755423">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஆடியோ ஃபைல்களை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஆடியோ ஃபைலை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_trash_video" formatted="false" msgid="4672871911555787438">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> வீடியோக்களை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த வீடியோவை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_trash_image" formatted="false" msgid="6400475304599873227">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> படங்களை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்தப் படத்தை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_trash_generic" formatted="false" msgid="3814167365075039711">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஃபைல்களை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஃபைலை நீக்கியவற்றிற்கு நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_untrash_audio" formatted="false" msgid="7795265980168966321">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஆடியோ ஃபைல்களை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஆடியோ ஃபைலை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_untrash_video" formatted="false" msgid="332894888445508879">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> வீடியோக்களை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த வீடியோவை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_untrash_image" formatted="false" msgid="7024071378733595056">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> படங்களை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்தப் படத்தை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_untrash_generic" formatted="false" msgid="6872817093731198374">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஃபைல்களை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஃபைலை நீக்கியவற்றில் இருந்து நகர்த்த <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_delete_audio" formatted="false" msgid="6848547621165184719">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஆடியோ ஃபைல்களை நீக்க <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஆடியோ ஃபைலை நீக்க <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_delete_video" formatted="false" msgid="1251942606336748563">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> வீடியோக்களை நீக்க <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த வீடியோவை நீக்க <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_delete_image" formatted="false" msgid="2303409455224710111">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> படங்களை நீக்க <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்தப் படத்தை நீக்க <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
-    <plurals name="permission_delete_generic" formatted="false" msgid="1412218850351841181">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ஃபைல்களை நீக்க <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-      <item quantity="one">இந்த ஃபைலை நீக்க <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?</item>
-    </plurals>
+    <!-- no translation found for permission_write_audio (8914759422381305478) -->
+    <!-- no translation found for permission_write_video (1098082003326873084) -->
+    <!-- no translation found for permission_write_image (748745548893845892) -->
+    <!-- no translation found for permission_write_generic (3270172714743671779) -->
+    <!-- no translation found for permission_trash_audio (8907813869381755423) -->
+    <!-- no translation found for permission_trash_video (4672871911555787438) -->
+    <!-- no translation found for permission_trash_image (6400475304599873227) -->
+    <!-- no translation found for permission_trash_generic (3814167365075039711) -->
+    <!-- no translation found for permission_untrash_audio (7795265980168966321) -->
+    <!-- no translation found for permission_untrash_video (332894888445508879) -->
+    <!-- no translation found for permission_untrash_image (7024071378733595056) -->
+    <!-- no translation found for permission_untrash_generic (6872817093731198374) -->
+    <!-- no translation found for permission_delete_audio (6848547621165184719) -->
+    <!-- no translation found for permission_delete_video (1251942606336748563) -->
+    <!-- no translation found for permission_delete_image (2303409455224710111) -->
+    <!-- no translation found for permission_delete_generic (1412218850351841181) -->
 </resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 30c0faa..d5ed82c 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -21,7 +21,7 @@
     <string name="app_label" msgid="9035307001052716210">"మీడియా నిల్వ"</string>
     <string name="artist_label" msgid="8105600993099120273">"కళాకారుడు"</string>
     <string name="unknown" msgid="2059049215682829375">"తెలియదు"</string>
-    <string name="root_images" msgid="5861633549189045666">"ఇమేజ్‌లు"</string>
+    <string name="root_images" msgid="5861633549189045666">"చిత్రాలు"</string>
     <string name="root_videos" msgid="8792703517064649453">"వీడియోలు"</string>
     <string name="root_audio" msgid="3505830755201326018">"ఆడియో"</string>
     <string name="root_documents" msgid="3829103301363849237">"డాక్యుమెంట్‌లు"</string>
@@ -29,82 +29,31 @@
     <string name="permission_required_action" msgid="706370952366113539">"కొనసాగించు"</string>
     <string name="grant_dialog_button_allow" msgid="1644287024501033471">"అనుమతించు"</string>
     <string name="grant_dialog_button_deny" msgid="6190589471415815741">"తిరస్కరించు"</string>
-    <plurals name="permission_more_thumb" formatted="false" msgid="4392079224649478923">
-      <item quantity="other">+<xliff:g id="COUNT_1">^1</xliff:g></item>
-      <item quantity="one">+<xliff:g id="COUNT_0">^1</xliff:g></item>
-    </plurals>
+    <!-- no translation found for permission_more_thumb (4392079224649478923) -->
     <plurals name="permission_more_text" formatted="false" msgid="7291997297174507324">
       <item quantity="other">దానితో పాటు, <xliff:g id="COUNT_1">^1</xliff:g> అదనపు అంశాలు</item>
       <item quantity="one">దానితో పాటు, <xliff:g id="COUNT_0">^1</xliff:g> అదనపు అంశం</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"తాత్కాలిక యాప్ ఫైల్‌లను క్లియర్ చేయండి"</string>
-    <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"కొన్ని తాత్కాలిక ఫైల్స్‌ను క్లియర్ చేయడానికి <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> అనుమతి కోరుతోంది. దీని వలన బ్యాటరీ లేదా సెల్యూలార్ డేటా వినియోగం పెరగవచ్చు."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"తాత్కాలిక యాప్ ఫైల్‌లను క్లియర్ చేస్తోంది…"</string>
-    <string name="clear" msgid="5524638938415865915">"క్లియర్ చేయండి"</string>
+    <!-- no translation found for cache_clearing_dialog_title (4672878017407595782) -->
+    <skip />
+    <!-- no translation found for cache_clearing_dialog_text (7057784635111940957) -->
+    <skip />
     <string name="allow" msgid="8885707816848569619">"అనుమతించు"</string>
     <string name="deny" msgid="6040983710442068936">"నిరాకరించు"</string>
-    <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఆడియో ఫైల్‌లను సవరించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఆడియో ఫైల్‌ను సవరించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_write_video" formatted="false" msgid="1098082003326873084">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> వీడియోలను సవరించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ వీడియోను సవరించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_write_image" formatted="false" msgid="748745548893845892">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఫోటోలను సవరించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఫోటోను సవరించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_write_generic" formatted="false" msgid="3270172714743671779">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఐటెమ్‌లను సవరించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఐటెమ్‌ను సవరించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_trash_audio" formatted="false" msgid="8907813869381755423">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఆడియో ఫైల్‌లను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఆడియో ఫైల్‌ను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_trash_video" formatted="false" msgid="4672871911555787438">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> వీడియోలను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ వీడియోను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_trash_image" formatted="false" msgid="6400475304599873227">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఫోటోలను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఫోటోను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_trash_generic" formatted="false" msgid="3814167365075039711">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఐటెమ్‌లను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఐటెమ్‌ను ట్రాష్‌కు తరలించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_untrash_audio" formatted="false" msgid="7795265980168966321">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఆడియో ఫైల్‌లను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఆడియో ఫైల్‌ను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_untrash_video" formatted="false" msgid="332894888445508879">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> వీడియోలను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ వీడియోను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_untrash_image" formatted="false" msgid="7024071378733595056">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఫోటోలను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఫోటోను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_untrash_generic" formatted="false" msgid="6872817093731198374">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఐటెమ్‌లను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఐటెమ్‌ను ట్రాష్ నుండి బయటకు తీయడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_delete_audio" formatted="false" msgid="6848547621165184719">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఆడియో ఫైల్‌లను తొలగించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఆడియో ఫైల్‌ను తొలగించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_delete_video" formatted="false" msgid="1251942606336748563">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> వీడియోలను తొలగించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ వీడియోను తొలగించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_delete_image" formatted="false" msgid="2303409455224710111">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఫోటోలను తొలగించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఫోటోను తొలగించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
-    <plurals name="permission_delete_generic" formatted="false" msgid="1412218850351841181">
-      <item quantity="other"><xliff:g id="COUNT">^2</xliff:g> ఐటెమ్‌లను తొలగించడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>ను అనుమతించాలా?</item>
-      <item quantity="one">ఈ ఐటెమ్‌ను తొలగించడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>ను అనుమతించాలా?</item>
-    </plurals>
+    <!-- no translation found for permission_write_audio (8914759422381305478) -->
+    <!-- no translation found for permission_write_video (1098082003326873084) -->
+    <!-- no translation found for permission_write_image (748745548893845892) -->
+    <!-- no translation found for permission_write_generic (3270172714743671779) -->
+    <!-- no translation found for permission_trash_audio (8907813869381755423) -->
+    <!-- no translation found for permission_trash_video (4672871911555787438) -->
+    <!-- no translation found for permission_trash_image (6400475304599873227) -->
+    <!-- no translation found for permission_trash_generic (3814167365075039711) -->
+    <!-- no translation found for permission_untrash_audio (7795265980168966321) -->
+    <!-- no translation found for permission_untrash_video (332894888445508879) -->
+    <!-- no translation found for permission_untrash_image (7024071378733595056) -->
+    <!-- no translation found for permission_untrash_generic (6872817093731198374) -->
+    <!-- no translation found for permission_delete_audio (6848547621165184719) -->
+    <!-- no translation found for permission_delete_video (1251942606336748563) -->
+    <!-- no translation found for permission_delete_image (2303409455224710111) -->
+    <!-- no translation found for permission_delete_generic (1412218850351841181) -->
 </resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index db76bee..d015e15 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">และอีก <xliff:g id="COUNT_1">^1</xliff:g> รายการ</item>
       <item quantity="one">และอีก <xliff:g id="COUNT_0">^1</xliff:g> รายการ</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ล้างไฟล์แอปชั่วคราว"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ล้างไฟล์แอปชั่วคราวใช่ไหม"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ต้องการล้างไฟล์ชั่วคราวบางไฟล์ ซึ่งอาจส่งผลให้ใช้แบตเตอรี่หรืออินเทอร์เน็ตมือถือมากขึ้น"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"กำลังล้างไฟล์แอปชั่วคราว…"</string>
-    <string name="clear" msgid="5524638938415865915">"ล้าง"</string>
     <string name="allow" msgid="8885707816848569619">"อนุญาต"</string>
     <string name="deny" msgid="6040983710442068936">"ปฏิเสธ"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 79452b3..a58d95c 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">At <xliff:g id="COUNT_1">^1</xliff:g> pang item</item>
       <item quantity="other">At <xliff:g id="COUNT_1">^1</xliff:g> pang item</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"I-clear ang mga pansamantalang file ng app"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"I-clear ang mga pansamantalang file ng app?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Gustong mag-clear ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ng ilang pansamantalang file. Baka lumakas ang paggamit ng baterya o cellular data dahil dito."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Kini-clear ang mga pansamantalang file ng app…"</string>
-    <string name="clear" msgid="5524638938415865915">"I-clear"</string>
     <string name="allow" msgid="8885707816848569619">"Payagan"</string>
     <string name="deny" msgid="6040983710442068936">"Tanggihan"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 669eac9..893ffca 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Ayrıca <xliff:g id="COUNT_1">^1</xliff:g> ek öğe</item>
       <item quantity="one">Ayrıca <xliff:g id="COUNT_0">^1</xliff:g> ek öğe</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Geçici uygulama dosyalarını temizleyin"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Geçici uygulama dosyaları temizlensin mi?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bazı geçici dosyaları temizlemek istiyor. Bu, pil veya hücresel veri kullanımında artışa yol açabilir."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Geçici uygulama dosyaları temizleniyor…"</string>
-    <string name="clear" msgid="5524638938415865915">"Temizle"</string>
     <string name="allow" msgid="8885707816848569619">"İzin ver"</string>
     <string name="deny" msgid="6040983710442068936">"Reddet"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 281c8b2..155d247 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -41,10 +41,8 @@
       <item quantity="many">Ще <xliff:g id="COUNT_1">^1</xliff:g> додаткових елементів</item>
       <item quantity="other">Ще <xliff:g id="COUNT_1">^1</xliff:g> додаткового елемента</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Видалити тимчасові файли додатків"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Видалити тимчасові файли додатків?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"Додаток <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> хоче видалити деякі тимчасові файли. Це може збільшити використання акумулятора або мобільного трафіку."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Видалення тимчасових файлів додатків…"</string>
-    <string name="clear" msgid="5524638938415865915">"Очистити"</string>
     <string name="allow" msgid="8885707816848569619">"Дозволити"</string>
     <string name="deny" msgid="6040983710442068936">"Заборонити"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index ad6cdf1..26f8b72 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">مزید <xliff:g id="COUNT_1">^1</xliff:g> اضافی آئٹمز</item>
       <item quantity="one">مزید <xliff:g id="COUNT_0">^1</xliff:g> اضافی آئٹم</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"ایپ کی عارضی فائلز کو صاف کریں"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"ایپ کی عارضی فائلز کو صاف کریں؟"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کچھ عارضی فائلز کو صاف کرنا چاہتی ہے۔ اس کی وجہ سے بیٹری یا سیلولر ڈیٹا کے استعمال میں اضافہ ہو سکتا ہے۔"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"ایپ کی عارضی فائلز کو صاف کیا جا رہا ہے…"</string>
-    <string name="clear" msgid="5524638938415865915">"صاف کریں"</string>
     <string name="allow" msgid="8885707816848569619">"اجازت دیں"</string>
     <string name="deny" msgid="6040983710442068936">"مسترد کریں"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 0dcad99..e947486 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Yana <xliff:g id="COUNT_1">^1</xliff:g> ta qoʻshimcha element</item>
       <item quantity="one">Yana <xliff:g id="COUNT_0">^1</xliff:g> ta qoʻshimcha element</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ilovaga oid vaqtincha fayllarni tozalash"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Ilovaga oid vaqtincha fayllar tozalansinmi?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ayrim vaqtincha fayllarni tozalamoqchi. Bunda batareya quvvati yoki internet trafigi ortiqcha sarflanishi mumkin."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Ilovaga oid vaqtincha fayllar tozalanmoqda…"</string>
-    <string name="clear" msgid="5524638938415865915">"Tozalash"</string>
     <string name="allow" msgid="8885707816848569619">"Ruxsat"</string>
     <string name="deny" msgid="6040983710442068936">"Rad etish"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index d0cbec7..922ec32 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">Và <xliff:g id="COUNT_1">^1</xliff:g> mục khác</item>
       <item quantity="one">Và <xliff:g id="COUNT_0">^1</xliff:g> mục khác</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Xóa tệp ứng dụng tạm thời"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Xóa tệp ứng dụng tạm thời?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> muốn xóa một số tệp tạm thời. Điều này có thể làm tăng mức sử dụng pin hoặc dữ liệu di động."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Đang xóa tệp ứng dụng tạm thời…"</string>
-    <string name="clear" msgid="5524638938415865915">"Xóa"</string>
     <string name="allow" msgid="8885707816848569619">"Cho phép"</string>
     <string name="deny" msgid="6040983710442068936">"Từ chối"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 6cd41f7..76c06ad 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">还有 <xliff:g id="COUNT_1">^1</xliff:g> 项</item>
       <item quantity="one">还有 <xliff:g id="COUNT_0">^1</xliff:g> 项</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"清除临时应用文件"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"要清除临时应用文件吗?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>请求清除一些临时文件。这可能消耗更多电量或数据流量。"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"正在清除临时应用文件…"</string>
-    <string name="clear" msgid="5524638938415865915">"清除"</string>
     <string name="allow" msgid="8885707816848569619">"允许"</string>
     <string name="deny" msgid="6040983710442068936">"拒绝"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 3243f9b..0025294 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">以及另外 <xliff:g id="COUNT_1">^1</xliff:g> 個項目</item>
       <item quantity="one">以及另外 <xliff:g id="COUNT_0">^1</xliff:g> 個項目</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"清除應用程式暫存檔案"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"要清除應用程式暫存檔案嗎?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」要求清除部分臨時檔案。這可能會導致耗電量或流動數據用量增加。"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"正在清除應用程式暫存檔案…"</string>
-    <string name="clear" msgid="5524638938415865915">"清除"</string>
     <string name="allow" msgid="8885707816848569619">"允許"</string>
     <string name="deny" msgid="6040983710442068936">"拒絕"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 1a37210..e5f5b48 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="other">還有另外 <xliff:g id="COUNT_1">^1</xliff:g> 個項目</item>
       <item quantity="one">還有另外 <xliff:g id="COUNT_0">^1</xliff:g> 個項目</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"清除應用程式暫存檔案"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"要清除應用程式暫存檔案嗎?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」想要清除某些暫存檔案,這可能會導致耗電量或行動數據用量增加。"</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"正在清除應用程式暫存檔案…"</string>
-    <string name="clear" msgid="5524638938415865915">"清除"</string>
     <string name="allow" msgid="8885707816848569619">"允許"</string>
     <string name="deny" msgid="6040983710442068936">"拒絕"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index e2f528d..e39d445 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -37,10 +37,8 @@
       <item quantity="one">Kanye no-<xliff:g id="COUNT_1">^1</xliff:g> izinto ezingeziwe</item>
       <item quantity="other">Kanye no-<xliff:g id="COUNT_1">^1</xliff:g> izinto ezingeziwe</item>
     </plurals>
-    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Sula amafayela ohlelo lokusebenza wesikhashana"</string>
+    <string name="cache_clearing_dialog_title" msgid="4672878017407595782">"Sula amafayela ohlelo lokusebenza wesikhashana?"</string>
     <string name="cache_clearing_dialog_text" msgid="7057784635111940957">"I-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ingathanda ukusula amanye amafayela esikhashana. Lokhu kungaholela ekusetshenzisweni kwebhethri okuphezulu noma kwedatha yeselula."</string>
-    <string name="cache_clearing_in_progress_title" msgid="6902220064511664209">"Isula amafayela wohlelo lokusebenza wesikhashana…"</string>
-    <string name="clear" msgid="5524638938415865915">"Sula"</string>
     <string name="allow" msgid="8885707816848569619">"Vumela"</string>
     <string name="deny" msgid="6040983710442068936">"Nqaba"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
diff --git a/sqlite3.sh b/sqlite3.sh
index 7f7780b..cf9b4a5 100644
--- a/sqlite3.sh
+++ b/sqlite3.sh
@@ -59,6 +59,26 @@
     adb shell am force-stop $package
 }
 
+function get-id-from-data () {
+    adb root
+    path="$1"
+    package=$(get-package)
+    dir="/data/user/0/$package/databases/external.db"
+    clause="\"select _id from files where _data='$path';\""
+    echo $clause
+    adb shell sqlite3 $dir $clause
+}
+
+function get-data-from-id () {
+    adb root
+    _id="$1"
+    package=$(get-package)
+    dir="/data/user/0/$package/databases/external.db"
+    clause="\"select _data from files where _id='$_id';\""
+    echo $clause
+    adb shell sqlite3 $dir $clause
+}
+
 function get-package() {
     if [ -z "$(adb shell pm list package com.android.providers.media.module)" ]
     then
diff --git a/src/com/android/providers/media/DatabaseHelper.java b/src/com/android/providers/media/DatabaseHelper.java
index 5130780..b6146be 100644
--- a/src/com/android/providers/media/DatabaseHelper.java
+++ b/src/com/android/providers/media/DatabaseHelper.java
@@ -800,7 +800,8 @@
                 + "writer TEXT DEFAULT NULL, exposure_time TEXT DEFAULT NULL,"
                 + "f_number TEXT DEFAULT NULL, iso INTEGER DEFAULT NULL,"
                 + "scene_capture_type INTEGER DEFAULT NULL, generation_added INTEGER DEFAULT 0,"
-                + "generation_modified INTEGER DEFAULT 0, xmp BLOB DEFAULT NULL)");
+                + "generation_modified INTEGER DEFAULT 0, xmp BLOB DEFAULT NULL,"
+                + "_transcode_status INTEGER DEFAULT 0, _video_codec_type TEXT DEFAULT NULL)");
 
         db.execSQL("CREATE TABLE log (time DATETIME, message TEXT)");
         if (!mInternal) {
@@ -1395,6 +1396,15 @@
                 + " AND " + MediaColumns.RELATIVE_PATH + " NOT LIKE '%/';");
     }
 
+    private static void updateAddTranscodeSatus(SQLiteDatabase db, boolean internal) {
+        db.execSQL("ALTER TABLE files ADD COLUMN _transcode_status INTEGER DEFAULT 0;");
+    }
+
+
+    private static void updateAddVideoCodecType(SQLiteDatabase db, boolean internal) {
+        db.execSQL("ALTER TABLE files ADD COLUMN _video_codec_type TEXT DEFAULT NULL;");
+    }
+
     private static void updateClearDirectories(SQLiteDatabase db, boolean internal) {
         db.execSQL("UPDATE files SET primary_directory=NULL, secondary_directory=NULL;");
     }
@@ -1536,7 +1546,10 @@
     static final int VERSION_P = 900;
     static final int VERSION_Q = 1023;
     static final int VERSION_R = 1115;
-    static final int VERSION_LATEST = VERSION_R;
+    // Leave some gaps in database version tagging to allow R schema changes
+    // to go independent of S schema changes.
+    static final int VERSION_S = 1201;
+    static final int VERSION_LATEST = VERSION_S;
 
     /**
      * This method takes care of updating all the tables in the database to the
@@ -1681,6 +1694,12 @@
             if (fromVersion < 1115) {
                 updateAudioAlbumId(db, internal);
             }
+            if (fromVersion < 1200) {
+                updateAddTranscodeSatus(db, internal);
+            }
+            if (fromVersion < 1201) {
+                updateAddVideoCodecType(db, internal);
+            }
 
             // If this is the legacy database, it's not worth recomputing data
             // values locally, since they'll be recomputed after the migration
diff --git a/src/com/android/providers/media/LocalCallingIdentity.java b/src/com/android/providers/media/LocalCallingIdentity.java
index 4d3700b..0d39f64 100644
--- a/src/com/android/providers/media/LocalCallingIdentity.java
+++ b/src/com/android/providers/media/LocalCallingIdentity.java
@@ -51,17 +51,19 @@
 import android.os.UserManager;
 import android.util.ArrayMap;
 
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 
 import com.android.providers.media.util.LongArray;
 
 public class LocalCallingIdentity {
-    public final Context context;
     public final int pid;
     public final int uid;
-    public final String packageNameUnchecked;
+    private final Context context;
+    private final String packageNameUnchecked;
     // Info used for logging permission checks
-    public @Nullable String attributionTag;
+    private final @Nullable String attributionTag;
+    private final Object lock = new Object();
 
     private LocalCallingIdentity(Context context, int pid, int uid, String packageNameUnchecked,
             @Nullable String attributionTag) {
@@ -140,8 +142,8 @@
         return ident;
     }
 
-    private String packageName;
-    private boolean packageNameResolved;
+    private volatile String packageName;
+    private volatile boolean packageNameResolved;
 
     public String getPackageName() {
         if (!packageNameResolved) {
@@ -158,8 +160,8 @@
         return packageNameUnchecked;
     }
 
-    private String[] sharedPackageNames;
-    private boolean sharedPackageNamesResolved;
+    private volatile String[] sharedPackageNames;
+    private volatile boolean sharedPackageNamesResolved;
 
     public String[] getSharedPackageNames() {
         if (!sharedPackageNamesResolved) {
@@ -174,8 +176,8 @@
         return (packageNames != null) ? packageNames : new String[0];
     }
 
-    private int targetSdkVersion;
-    private boolean targetSdkVersionResolved;
+    private volatile int targetSdkVersion;
+    private volatile boolean targetSdkVersionResolved;
 
     public int getTargetSdkVersion() {
         if (!targetSdkVersionResolved) {
@@ -216,8 +218,8 @@
 
     public static final int PERMISSION_IS_SYSTEM_GALLERY = 1 <<22;
 
-    private int hasPermission;
-    private int hasPermissionResolved;
+    private volatile int hasPermission;
+    private volatile int hasPermissionResolved;
 
     public boolean hasPermission(int permission) {
         if ((hasPermissionResolved & permission) == 0) {
@@ -336,42 +338,54 @@
         return false;
     }
 
-    private LongArray ownedIds = new LongArray();
+    @GuardedBy("lock")
+    private final LongArray ownedIds = new LongArray();
 
     public boolean isOwned(long id) {
-        return ownedIds.indexOf(id) != -1;
+        synchronized (lock) {
+            return ownedIds.indexOf(id) != -1;
+        }
     }
 
     public void setOwned(long id, boolean owned) {
-        final int index = ownedIds.indexOf(id);
-        if (owned) {
-            if (index == -1) {
-                ownedIds.add(id);
-            }
-        } else {
-            if (index != -1) {
-                ownedIds.remove(index);
+        synchronized (lock) {
+            final int index = ownedIds.indexOf(id);
+            if (owned) {
+                if (index == -1) {
+                    ownedIds.add(id);
+                }
+            } else {
+                if (index != -1) {
+                    ownedIds.remove(index);
+                }
             }
         }
     }
 
-    private ArrayMap<String, Long> rowIdOfDeletedPaths = new ArrayMap<>();
+    @GuardedBy("lock")
+    private final ArrayMap<String, Long> rowIdOfDeletedPaths = new ArrayMap<>();
 
     public void addDeletedRowId(@NonNull String path, long id) {
-        rowIdOfDeletedPaths.put(path, id);
+        synchronized (lock) {
+            rowIdOfDeletedPaths.put(path, id);
+        }
     }
 
     public boolean removeDeletedRowId(long id) {
-        int index = rowIdOfDeletedPaths.indexOfValue(id);
-        final boolean isDeleted = index > -1;
-        while (index > -1) {
-            rowIdOfDeletedPaths.removeAt(index);
-            index = rowIdOfDeletedPaths.indexOfValue(id);
+        synchronized (lock) {
+            int index = rowIdOfDeletedPaths.indexOfValue(id);
+            final boolean isDeleted = index > -1;
+            while (index > -1) {
+                rowIdOfDeletedPaths.removeAt(index);
+                index = rowIdOfDeletedPaths.indexOfValue(id);
+            }
+            return isDeleted;
         }
-        return isDeleted;
     }
 
     public long getDeletedRowId(@NonNull String path) {
-        return rowIdOfDeletedPaths.getOrDefault(path, UNKNOWN_ROW_ID);
+        synchronized (lock) {
+            return rowIdOfDeletedPaths.getOrDefault(path, UNKNOWN_ROW_ID);
+        }
     }
 }
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 22676a8..c4097c9 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -24,6 +24,7 @@
 import static android.content.ContentResolver.QUERY_ARG_SQL_SELECTION;
 import static android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.provider.MediaStore.EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT;
 import static android.provider.MediaStore.MATCH_DEFAULT;
 import static android.provider.MediaStore.MATCH_EXCLUDE;
 import static android.provider.MediaStore.MATCH_INCLUDE;
@@ -236,10 +237,10 @@
     static final Pattern PATTERN_SELECTION_ID = Pattern.compile(
             "(?:image_id|video_id)\\s*=\\s*(\\d+)");
 
-    /**
-     * Property that indicates whether fuse is enabled.
-     */
-    private static final String PROP_FUSE = "persist.sys.fuse";
+    /** File supports transforms and uid requires transcoding */
+    private static final int FLAG_TRANSFORM_TRANSCODING = 1;
+    /** File supports transforms */
+    private static final int FLAG_TRANSFORM_SUPPORTED = 1 << 30;
 
     /**
      * These directory names aren't declared in Environment as final variables, and so we need to
@@ -438,7 +439,6 @@
 
     private int mExternalStorageAuthorityAppId;
     private int mDownloadsAuthorityAppId;
-
     private Size mThumbSize;
 
     /**
@@ -692,6 +692,9 @@
                 int mediaType, boolean isDownload, String ownerPackageName, String path) {
             handleDeletedRowForFuse(path, ownerPackageName, id);
             acceptWithExpansion(helper::notifyDelete, volumeName, id, mediaType, isDownload);
+            // Remove cached transcoded file if any
+            mTranscodeHelper.deleteCachedTranscodeFile(id);
+
 
             helper.postBackground(() -> {
                 // Item no longer exists, so revoke all access to it
@@ -923,6 +926,8 @@
                 false, false, false, Column.class,
                 Metrics::logSchemaChange, mFilesListener, MIGRATION_LISTENER, mIdGenerator);
 
+        mTranscodeHelper = new TranscodeHelper(context, this);
+
         final IntentFilter packageFilter = new IntentFilter();
         packageFilter.setPriority(10);
         packageFilter.addDataScheme("package");
@@ -973,10 +978,10 @@
             // throw an IllegalArgumentException during MediaProvider startup. In combination with
             // MediaProvider's CTS tests it should give us guarantees that OPSTR_NO_ISOLATED_STORAGE
             // is defined.
-            mAppOpsManager.startWatchingMode(PermissionUtils.OPSTR_NO_ISOLATED_STORAGE,
+            mAppOpsManager.startWatchingMode(AppOpsManager.OPSTR_NO_ISOLATED_STORAGE,
                     null /* all packages */, mModeListener);
         } catch (IllegalArgumentException e) {
-            Log.w(TAG, "Failed to start watching " + PermissionUtils.OPSTR_NO_ISOLATED_STORAGE, e);
+            Log.w(TAG, "Failed to start watching " + AppOpsManager.OPSTR_NO_ISOLATED_STORAGE, e);
         }
 
         ProviderInfo provider = mPackageManager.resolveContentProvider(
@@ -1087,7 +1092,7 @@
         });
         Log.d(TAG, "Pruned " + stalePackages + " unknown packages");
 
-        // Delete any expired content; we're paranoid about wildly changing
+        // Delete any expired content; we're cautious about wildly changing
         // clocks, so only delete items within the last week
         final long from = ((System.currentTimeMillis() - DateUtils.WEEK_IN_MILLIS) / 1000);
         final long to = (System.currentTimeMillis() / 1000);
@@ -1228,6 +1233,7 @@
             return false;
         }
         boolean result = isAppCloneUserPair(0, userId);
+
         Log.w(TAG, "isAppCloneUserPair for user " + userId + ": " + result);
 
         return result;
@@ -1301,6 +1307,77 @@
     }
 
     /**
+     * Called from FUSE to transform a file
+     *
+     * A transform can change the file contents for {@code uid} from {@code src} to {@code dst}
+     * depending on {@code flags}. This allows the FUSE daemon serve different file contents for
+     * the same file to different apps.
+     *
+     * The only supported transform for now is transcoding which re-encodes a file taken in a modern
+     * format like HEVC to a legacy format like AVC.
+     *
+     * @param src file path to transform
+     * @param dst file path to save transformed file
+     * @param flags determines the kind of transform
+     * @param uid app requesting transform
+     *
+     * Called from JNI in jni/MediaProviderWrapper.cpp
+     */
+    @Keep
+    public boolean transformForFuse(String src, String dst, int transforms, int uid) {
+        if ((transforms & FLAG_TRANSFORM_TRANSCODING) != 0) {
+            if (mTranscodeHelper.isTranscodeFileCached(src, dst)) {
+                Log.d(TAG, "Using transcode cache for " + src);
+                return true;
+            }
+            return mTranscodeHelper.transcode(src, dst, uid);
+        }
+        return true;
+    }
+
+    /**
+     * Called from FUSE to get IO path for {@code uid}
+     *
+     * IO path is the actual path to be used on the lower fs for IO via FUSE. For some file
+     * transforms, this path might be different from the path the app is requesting IO on.
+     *
+     * @param path file path to get an IO path for
+     * @param uid app requesting IO
+     *
+     * Called from JNI in jni/MediaProviderWrapper.cpp
+     */
+    @Keep
+    public String getIoPathForFuse(String path, int uid) {
+        return mTranscodeHelper.getIoPath(path, uid);
+    }
+
+    /**
+     * Called from FUSE to get transforms for {@code uid}
+     *
+     * If transforms are not supported for {@code path}, {@code 0} will be returned. Otherwise,
+     * a bitwise OR of supported transforms for {@code path} and actual transforms to perform for
+     * {@code uid} will be returned.
+     *
+     * @param path file path to get transforms for
+     * @param uid app requesting IO
+     *
+     * Called from JNI in jni/MediaProviderWrapper.cpp
+     * @see {@link transformForFuse}
+     */
+    @Keep
+    public int getTransformsForFuse(String path, int uid) {
+        int result = 0;
+        if (mTranscodeHelper.supportsTranscode(path)) {
+            result |= FLAG_TRANSFORM_SUPPORTED;
+
+            if (mTranscodeHelper.shouldTranscode(path, uid)) {
+                result |= FLAG_TRANSFORM_TRANSCODING;
+            }
+        }
+        return result;
+    }
+
+    /**
      * Returns true if the app denoted by the given {@code uid} and {@code packageName} is allowed
      * to clear other apps' cache directories.
      */
@@ -2569,7 +2646,7 @@
 
     /**
      * Get the various file-related {@link MediaColumns} in the given
-     * {@link ContentValues} into sane condition. Also validates that defined
+     * {@link ContentValues} into a consistent condition. Also validates that defined
      * columns are valid for the given {@link Uri}, such as ensuring that only
      * {@code image/*} can be inserted into
      * {@link android.provider.MediaStore.Images}.
@@ -2736,7 +2813,7 @@
             }
         }
 
-        // Give ourselves sane defaults when missing
+        // Give ourselves reasonable defaults when missing
         if (TextUtils.isEmpty(values.getAsString(MediaColumns.DISPLAY_NAME))) {
             values.put(MediaColumns.DISPLAY_NAME,
                     String.valueOf(System.currentTimeMillis()));
@@ -2748,7 +2825,7 @@
         }
 
         mimeType = values.getAsString(MediaColumns.MIME_TYPE);
-        // Sanity check MIME type against table
+        // Quick check MIME type against table
         if (mimeType != null) {
             final int actualMediaType = MimeUtils.resolveMediaType(mimeType);
             if (defaultMediaType == FileColumns.MEDIA_TYPE_NONE) {
@@ -2920,7 +2997,7 @@
             // files DISPLAY_NAME will not be same as file name.
             FileUtils.computeValuesFromData(values, isFuseThread);
         } else {
-            assertFileColumnsSane(match, uri, values);
+            assertFileColumnsConsistent(match, uri, values);
         }
 
         // Drop columns that aren't relevant for special tables
@@ -2943,8 +3020,7 @@
 
     /**
      * @return the default dir if {@code file} is a child of default dir and it's missing,
-     * {@code null} otherwise.
-     */
+     * {@code null} otherwise. */
     private File checkDefaultDirMissing(String volumeName, File file) {
         String topLevelDir = FileUtils.extractTopLevelDir(file.getPath());
         if (topLevelDir != null && FileUtils.isDefaultDirectoryName(topLevelDir)) {
@@ -2977,13 +3053,13 @@
      * Check that any requested {@link MediaColumns#DATA} paths actually
      * live on the storage volume being targeted.
      */
-    private void assertFileColumnsSane(int match, Uri uri, ContentValues values)
+    private void assertFileColumnsConsistent(int match, Uri uri, ContentValues values)
             throws VolumeArgumentException, VolumeNotFoundException {
         if (!values.containsKey(MediaColumns.DATA)) return;
 
         final String volumeName = resolveVolumeName(uri);
         try {
-            // Sanity check that the requested path actually lives on volume
+            // Quick check that the requested path actually lives on volume
             final Collection<File> allowed = getVolumeScanPaths(volumeName);
             final File actual = new File(values.getAsString(MediaColumns.DATA))
                     .getCanonicalFile();
@@ -3900,6 +3976,14 @@
         }
     }
 
+    /**
+     * Gets shared package names for the calling package
+     * TODO(b/170465810) Change the method name after refactoring.
+     */
+    String[] getSharedPackagesForUidForTranscoding(int uid) {
+        return getContext().getPackageManager().getPackagesForUid(uid);
+    }
+
     @Deprecated
     private String getSharedPackages() {
         final String[] sharedPackageNames = mCallingIdentity.get().getSharedPackageNames();
@@ -3925,6 +4009,15 @@
     private static final int TYPE_DELETE = 3;
 
     /**
+     * Creating a new method for Transcoding to avoid any merge conflicts.
+     * TODO(b/170465810): Remove this when getQueryBuilder code is refactored.
+     */
+    @NonNull SQLiteQueryBuilder getQueryBuilderForTranscoding(int type, int match,
+            @NonNull Uri uri, @NonNull Bundle extras, @Nullable Consumer<String> honored) {
+        return getQueryBuilder(type, match, uri, extras, honored);
+    }
+
+    /**
      * Generate a {@link SQLiteQueryBuilder} that is filtered based on the
      * runtime permissions and/or {@link Uri} grants held by the caller.
      * <ul>
@@ -4260,7 +4353,7 @@
             case AUDIO_ARTISTS_ID_ALBUMS: {
                 if (type == TYPE_QUERY) {
                     qb.setTables("audio_albums");
-                    qb.setProjectionMap(getProjectionMap(Audio.Albums.class));
+                    qb.setProjectionMap(getProjectionMap(Audio.Artists.Albums.class));
 
                     final String artistId = uri.getPathSegments().get(3);
                     appendWhereStandalone(qb, "artist_id=?", artistId);
@@ -4924,7 +5017,7 @@
 
     /**
      * Generate the {@link PendingIntent} for the given grant request. This
-     * method also sanity checks the incoming arguments for security purposes
+     * method also checks the incoming arguments for security purposes
      * before creating the privileged {@link PendingIntent}.
      */
     private @NonNull PendingIntent createRequest(@NonNull String method, @NonNull Bundle extras) {
@@ -5006,7 +5099,7 @@
      *         {@code ORDER BY} clauses.
      */
     private @NonNull String ensureCustomCollator(@NonNull String locale) {
-        // Quick sanity check that requested locale looks sane
+        // Quick check that requested locale looks reasonable
         new ULocale(locale);
 
         final String collationName = "custom_" + locale.replaceAll("[^a-zA-Z]", "");
@@ -5621,8 +5714,8 @@
             Trace.endSection();
         }
 
-        // Make sure any updated paths look sane
-        assertFileColumnsSane(match, uri, initialValues);
+        // Make sure any updated paths look consistent
+        assertFileColumnsConsistent(match, uri, initialValues);
 
         if (initialValues.containsKey(FileColumns.DATA)) {
             // If we're changing paths, invalidate any thumbnails
@@ -6101,18 +6194,20 @@
 
     @Override
     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
-        return openFileCommon(uri, mode, null);
+        return openFileCommon(uri, mode, /*signal*/ null, /*opts*/ null);
     }
 
     @Override
     public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
             throws FileNotFoundException {
-        return openFileCommon(uri, mode, signal);
+        return openFileCommon(uri, mode, signal, /*opts*/ null);
     }
 
-    private ParcelFileDescriptor openFileCommon(Uri uri, String mode, CancellationSignal signal)
+    private ParcelFileDescriptor openFileCommon(Uri uri, String mode, CancellationSignal signal,
+            @Nullable Bundle opts)
             throws FileNotFoundException {
         uri = safeUncanonicalize(uri);
+        opts = opts == null ? new Bundle() : opts;
 
         final boolean allowHidden = isCallingPackageAllowedHidden();
         final int match = matchUri(uri, allowHidden);
@@ -6146,7 +6241,7 @@
             }
         }
 
-        return openFileAndEnforcePathPermissionsHelper(uri, match, mode, signal);
+        return openFileAndEnforcePathPermissionsHelper(uri, match, mode, signal, opts);
     }
 
     @Override
@@ -6176,7 +6271,7 @@
         }
 
         // Worst case, return the underlying file
-        return new AssetFileDescriptor(openFileCommon(uri, "r", signal), 0,
+        return new AssetFileDescriptor(openFileCommon(uri, "r", signal, opts), 0,
                 AssetFileDescriptor.UNKNOWN_LENGTH);
     }
 
@@ -6380,6 +6475,22 @@
         return new File(filePath);
     }
 
+    private ParcelFileDescriptor openWithTranscode(String filePath, int uid, int modeBits)
+            throws FileNotFoundException {
+        String transcodePath = mTranscodeHelper.getIoPath(filePath, uid);
+        File transcodeFile = new File(transcodePath);
+
+        if (mTranscodeHelper.isTranscodeFileCached(filePath, transcodePath)) {
+            Log.d(TAG, "Using FUSE with transcode cache for " + filePath + " Uid: " + uid);
+            return FileUtils.openSafely(getFuseFile(transcodeFile), modeBits);
+        } else if (mTranscodeHelper.transcode(filePath, transcodePath, uid)) {
+            Log.d(TAG, "Using FUSE with transcode for " + filePath + " Uid: " + uid);
+            return FileUtils.openSafely(getFuseFile(transcodeFile), modeBits);
+        } else {
+            throw new FileNotFoundException("Failed to transcode " + filePath);
+        }
+    }
+
     private @NonNull FuseDaemon getFuseDaemonForFile(@NonNull File file)
             throws FileNotFoundException {
         final FuseDaemon daemon = ExternalStorageServiceImpl.getFuseDaemon(getVolumeId(file));
@@ -6418,7 +6529,8 @@
      * a "/mnt/user" path.
      */
     private ParcelFileDescriptor openFileAndEnforcePathPermissionsHelper(Uri uri, int match,
-            String mode, CancellationSignal signal) throws FileNotFoundException {
+            String mode, CancellationSignal signal, @NonNull Bundle opts)
+            throws FileNotFoundException {
         int modeBits = ParcelFileDescriptor.parseMode(mode);
         boolean forWrite = (modeBits & ParcelFileDescriptor.MODE_WRITE_ONLY) != 0;
         if (forWrite) {
@@ -6507,33 +6619,31 @@
             // First, handle any redaction that is needed for caller
             final ParcelFileDescriptor pfd;
             final String filePath = file.getPath();
+            final int uid = Binder.getCallingUid();
+            final boolean shouldTranscode = !opts.containsKey(EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT)
+                    && mTranscodeHelper.shouldTranscode(filePath, uid);
             if (redactionInfo.redactionRanges.length > 0) {
-                if (SystemProperties.getBoolean(PROP_FUSE, false)) {
-                    // If fuse is enabled, we can provide an fd that points to the fuse
-                    // file system and handle redaction in the fuse handler when the caller reads.
-                    Log.i(TAG, "Redacting with new FUSE for " + filePath);
-                    long tid = android.os.Process.myTid();
-                    synchronized (mShouldRedactThreadIds) {
-                        mShouldRedactThreadIds.add(tid);
-                    }
-                    try {
-                        pfd = FileUtils.openSafely(getFuseFile(file), modeBits);
-                    } finally {
-                        synchronized (mShouldRedactThreadIds) {
-                            mShouldRedactThreadIds.remove(mShouldRedactThreadIds.indexOf(tid));
-                        }
-                    }
-                } else {
-                    // TODO(b/135341978): Remove this and associated code
-                    // when fuse is on by default.
-                    Log.i(TAG, "Redacting with old FUSE for " + filePath);
-                    pfd = RedactingFileDescriptor.open(
-                            getContext(),
-                            file,
-                            modeBits,
-                            redactionInfo.redactionRanges,
-                            redactionInfo.freeOffsets);
+                // If fuse is enabled, we can provide an fd that points to the fuse
+                // file system and handle redaction in the fuse handler when the caller reads.
+                Log.i(TAG, "Redacting with new FUSE for " + filePath);
+                long tid = android.os.Process.myTid();
+                synchronized (mShouldRedactThreadIds) {
+                    mShouldRedactThreadIds.add(tid);
                 }
+
+                try {
+                    if (shouldTranscode) {
+                        pfd = openWithTranscode(filePath, uid, modeBits);
+                    } else {
+                        pfd = FileUtils.openSafely(getFuseFile(file), modeBits);
+                    }
+                } finally {
+                    synchronized (mShouldRedactThreadIds) {
+                        mShouldRedactThreadIds.remove(mShouldRedactThreadIds.indexOf(tid));
+                    }
+                }
+            } else if (shouldTranscode) {
+                pfd = openWithTranscode(filePath, uid, modeBits);
             } else {
                 FuseDaemon daemon = null;
                 try {
@@ -6546,12 +6656,12 @@
                 boolean shouldOpenWithFuse = daemon != null
                         && daemon.shouldOpenWithFuse(filePath, true /* forRead */, lowerFsFd.getFd());
 
-                if (SystemProperties.getBoolean(PROP_FUSE, false) && shouldOpenWithFuse) {
+                if (shouldOpenWithFuse) {
                     // If the file is already opened on the FUSE mount with VFS caching enabled
                     // we return an upper filesystem fd (via FUSE) to avoid file corruption
                     // resulting from cache inconsistencies between the upper and lower
                     // filesystem caches
-                    Log.w(TAG, "Using FUSE for " + filePath);
+                    Log.w(TAG, "Using FUSE for " + filePath + ". Uid: " + uid);
                     pfd = FileUtils.openSafely(getFuseFile(file), modeBits);
                     try {
                         lowerFsFd.close();
@@ -6559,7 +6669,7 @@
                         Log.w(TAG, "Failed to close lower filesystem fd " + file.getPath(), e);
                     }
                 } else {
-                    Log.i(TAG, "Using lower FS for " + filePath);
+                    Log.i(TAG, "Using lower FS for " + filePath + ". Uid: " + uid);
                     if (forWrite) {
                         // When opening for write on the lower filesystem, invalidate the VFS dentry
                         // so subsequent open/getattr calls will return correctly.
@@ -7033,7 +7143,7 @@
             //   couldn't return a valid db row, or,
             // * There is no db row corresponding to the requested path, which is more unlikely.
             // In both of these cases, it means that app doesn't have access permission to the file.
-            Log.e(TAG, "Couldn't find file: " + path);
+            Log.e(TAG, "Couldn't find file: " + path, e);
             return OsConstants.EACCES;
         } catch (IllegalStateException | SecurityException e) {
             Log.e(TAG, "Permission to access file: " + path + " is denied");
@@ -7690,7 +7800,7 @@
         // First, does caller have the needed row-level access?
         enforceCallingPermission(uri, extras, isWrite);
 
-        // Second, does the path look sane?
+        // Second, does the path look consistent?
         if (!FileUtils.contains(Environment.getStorageDirectory(), file)) {
             checkWorldReadAccess(file.getAbsolutePath());
         }
@@ -7827,6 +7937,15 @@
         }
     }
 
+    /**
+     * Creating a new method for Transcoding to avoid any merge conflicts.
+     * TODO(b/170465810): Remove this when the code is refactored.
+     */
+    @NonNull DatabaseHelper getDatabaseForUriForTranscoding(Uri uri)
+            throws VolumeNotFoundException {
+        return getDatabaseForUri(uri);
+    }
+
     private @NonNull DatabaseHelper getDatabaseForUri(Uri uri) throws VolumeNotFoundException {
         final String volumeName = resolveVolumeName(uri);
         synchronized (mAttachedVolumeNames) {
@@ -7871,10 +7990,10 @@
                     "Opening and closing databases not allowed.");
         }
 
-        // Quick sanity check for shady volume names
+        // Quick check for shady volume names
         MediaStore.checkArgumentVolumeName(volume);
 
-        // Quick sanity check that volume actually exists
+        // Quick check that volume actually exists
         if (!MediaStore.VOLUME_INTERNAL.equals(volume) && validate) {
             try {
                 getVolumePath(volume);
@@ -7925,7 +8044,7 @@
                     "Opening and closing databases not allowed.");
         }
 
-        // Quick sanity check for shady volume names
+        // Quick check for shady volume names
         MediaStore.checkArgumentVolumeName(volume);
 
         if (MediaStore.VOLUME_INTERNAL.equals(volume)) {
@@ -7961,6 +8080,7 @@
 
     private DatabaseHelper mInternalDatabase;
     private DatabaseHelper mExternalDatabase;
+    private TranscodeHelper mTranscodeHelper;
 
     // name of the volume currently being scanned by the media scanner (or null)
     private String mMediaScannerVolume;
diff --git a/src/com/android/providers/media/TranscodeHelper.java b/src/com/android/providers/media/TranscodeHelper.java
new file mode 100644
index 0000000..b3ae5ac
--- /dev/null
+++ b/src/com/android/providers/media/TranscodeHelper.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.providers.media;
+
+import static android.provider.MediaStore.Files.FileColumns.TRANSCODE_COMPLETE;
+import static android.provider.MediaStore.Files.FileColumns.TRANSCODE_EMPTY;
+import static android.provider.MediaStore.MATCH_EXCLUDE;
+import static android.provider.MediaStore.QUERY_ARG_MATCH_PENDING;
+import static android.provider.MediaStore.QUERY_ARG_MATCH_TRASHED;
+
+import static com.android.providers.media.MediaProvider.VolumeNotFoundException;
+import android.widget.Toast;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.media.MediaFormat;
+import android.media.MediaTranscodeManager;
+import android.media.MediaTranscodeManager.TranscodingSession;
+import android.media.MediaTranscodeManager.TranscodingRequest;
+import android.media.MediaTranscodingException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Environment;
+import android.os.SystemProperties;
+import android.provider.MediaStore.Files.FileColumns;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.providers.media.util.FileUtils;
+import com.android.providers.media.util.ForegroundThread;
+import com.android.providers.media.util.SQLiteQueryBuilder;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class TranscodeHelper {
+    private static final String TAG = "TranscodeHelper";
+    private static final String TRANSCODE_FILE_PREFIX = ".transcode_";
+
+    /** Coefficient to 'guess' how long a transcoding session might take */
+    private static final double TRANSCODING_TIMEOUT_COEFFICIENT = 2;
+    /** Coefficient to 'guess' how large a transcoded file might be */
+    private static final double TRANSCODING_SIZE_COEFFICIENT = 2;
+
+    /**
+     * Copied from MediaProvider.java
+     * TODO(b/170465810): Remove this when  getQueryBuilder code is refactored.
+     */
+    private static final int TYPE_QUERY = 0;
+    private static final int TYPE_UPDATE = 2;
+    static final String DIRECTORY_CAMERA = "Camera";
+
+    private final Context mContext;
+    private final MediaProvider mMediaProvider;
+    private final MediaTranscodeManager mMediaTranscodeManager;
+    private final Handler mUiHandler;
+    private final File mTranscodeDirectory;
+    @GuardedBy("mTranscodingSessions")
+    private final Map<String, TranscodingSession> mTranscodingSessions = new ArrayMap<>();
+    @GuardedBy("mTranscodingSessions")
+    private final SparseArray<CountDownLatch> mTranscodingLatches = new SparseArray<>();
+
+    private static final String[] TRANSCODE_CACHE_INFO_PROJECTION =
+            {FileColumns._ID, FileColumns._TRANSCODE_STATUS};
+    private static final String TRANSCODE_WHERE_CLAUSE =
+            FileColumns.DATA + "=?" + " and mime_type not like 'null'";
+
+    /**
+     * Never transcode for these packages.
+     * TODO(b/169327180): Replace this with allow list from server.
+     */
+    private static final String[] ALLOW_LIST = new String[0];
+    /**
+     * Force transcode for these package names.
+     * TODO(b/169849854): Remove this when app capabilities can be used to make this decision.
+     */
+    private static String[] TRANSCODE_LIST = new String[] {
+            "com.facebook.katana",
+            "com.google.android.talk",
+            "com.snapchat.android",
+            "com.instagram.android",
+            // TODO: Add "com.google.android.apps.photos", to teamfood after investigating issue
+            "com.linecorp.b612.android",
+            "com.zhiliaoapp.musically",
+            "com.tencent.mm"
+    };
+
+    public TranscodeHelper(Context context, MediaProvider mediaProvider) {
+        mContext = context;
+        mMediaTranscodeManager = context.getSystemService(MediaTranscodeManager.class);
+        mMediaProvider = mediaProvider;
+        mUiHandler = new Handler(Looper.getMainLooper());
+        mTranscodeDirectory =
+                FileUtils.buildPath(Environment.getExternalStorageDirectory(), DIRECTORY_TRANSCODE);
+        mTranscodeDirectory.mkdirs();
+    }
+
+    /**
+     * Regex that matches path of transcode file. The regex only
+     * matches emulated volume, for files in other volumes we don't
+     * seamlessly transcode.
+     */
+    private static final Pattern PATTERN_TRANSCODE_PATH = Pattern.compile(
+            "(?i)^/storage/emulated/(?:[0-9]+)/\\.transcode/(?:\\d+)$");
+    private static final String DIRECTORY_TRANSCODE = ".transcode";
+
+    /**
+     * @return true if the file path matches transcode file path.
+     */
+    public static boolean isTranscodeFile(@NonNull String path) {
+        final Matcher matcher = PATTERN_TRANSCODE_PATH.matcher(path);
+        return matcher.matches();
+    }
+
+    @NonNull
+    public File getTranscodeDirectory() {
+        return mTranscodeDirectory;
+    }
+
+    /**
+     * @return transcode file's path for given {@code rowId}
+     */
+    @NonNull
+    public String getTranscodePath(long rowId) {
+        return new File(getTranscodeDirectory(), String.valueOf(rowId)).getAbsolutePath();
+    }
+
+    public boolean transcode(String src, String dst, int uid) {
+        TranscodingSession session = null;
+        CountDownLatch latch = null;
+
+        synchronized (mTranscodingSessions) {
+            session = mTranscodingSessions.get(src);
+            if (session == null) {
+                latch = new CountDownLatch(1);
+                try {
+                    session = enqueueTranscodingSession(src, dst, uid, latch);
+                } catch (MediaTranscodingException | FileNotFoundException e) {
+                    throw new IllegalStateException(e);
+                }
+
+                mTranscodingLatches.put(session.getSessionId(), latch);
+                mTranscodingSessions.put(src, session);
+            } else {
+                latch = mTranscodingLatches.get(session.getSessionId());
+                if (latch == null) {
+                    throw new IllegalStateException("Expected latch for" + session);
+                }
+            }
+        }
+
+        boolean result = waitTranscodingResult(uid, src, session, latch);
+        if (result) {
+            updateTranscodeStatus(src, TRANSCODE_COMPLETE);
+        } else {
+            logEvent("Transcoding failed for " + src + ". session: ", true /* toast */, session);
+            // Attempt to workaround media transcoding deadlock, b/165374867
+            // Cancelling a deadlocked session seems to unblock the transcoder
+            finishTranscodingResult(uid, src, session, latch);
+        }
+        return result;
+    }
+
+    public String getIoPath(String path, int uid) {
+        if (!shouldTranscode(path, uid)) {
+            return path;
+        }
+
+        Pair<Long, Integer> cacheInfo = getTranscodeCacheInfoFromDB(path);
+        final long rowId =cacheInfo.first;
+        if (rowId == -1 ) {
+            // No database row found, The file is pending/trashed or not added to database yet.
+            // Assuming that no transcoding needed.
+            return path;
+        }
+
+        int transcodeStatus = cacheInfo.second;
+        final String transcodePath = getTranscodePath(rowId);
+        final File transcodeFile = new File(transcodePath);
+
+        if (transcodeFile.exists()) {
+            return transcodePath;
+        }
+
+        if (transcodeStatus == TRANSCODE_COMPLETE) {
+            // The transcode file doesn't exist but db row is marked as TRANSCODE_COMPLETE,
+            // update db row to TRANSCODE_EMPTY so that cache state remains valid.
+            updateTranscodeStatus(path, TRANSCODE_EMPTY);
+        }
+
+        final File file = new File(path);
+        long maxFileSize = (long) (file.length() * 2);
+        getTranscodeDirectory().mkdirs();
+        try (RandomAccessFile raf = new RandomAccessFile(transcodeFile, "rw")) {
+            raf.setLength(maxFileSize);
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to initialise transcoding for file " + path, e);
+            return path;
+        }
+
+        return transcodePath;
+    }
+
+    public boolean shouldTranscode(String path, int uid) {
+        final boolean transcodeEnabled
+                = SystemProperties.getBoolean("persist.fuse.sys.transcode", false);
+        if (!transcodeEnabled) {
+            return false;
+        }
+
+        if (!supportsTranscode(path) || uid < android.os.Process.FIRST_APPLICATION_UID) {
+            return false;
+        }
+
+        // Transcode only if file needs transcoding
+        try (Cursor cursor = queryFileForTranscode(path,
+                new String[] {FileColumns._VIDEO_CODEC_TYPE})) {
+            if (cursor == null || !cursor.moveToNext()) {
+                Log.d(TAG, "Couldn't find database row for path " + path +
+                        ", Assuming no seamless transcoding needed.");
+                return false;
+            }
+            if (!MediaFormat.MIMETYPE_VIDEO_HEVC.equalsIgnoreCase(cursor.getString(0))) {
+                return false;
+            }
+        }
+
+        // TODO(b/169327180): We should also check app's targetSDK version to verify if app still
+        //  qualifies to be on the allow list.
+        List<String> allowList = Arrays.asList(ALLOW_LIST);
+        List<String> transcodeList = Arrays.asList(TRANSCODE_LIST);
+        final String[] callingPackages = mMediaProvider.getSharedPackagesForUidForTranscoding(uid);
+        for (String callingPackage: callingPackages) {
+            if (allowList.contains(callingPackage)) {
+                return false;
+            }
+            if (transcodeList.contains(callingPackage)) {
+                return true;
+            }
+        }
+
+        int supportedUid = SystemProperties.getInt("fuse.sys.transcode_uid", -2);
+        if ((supportedUid == uid) || (supportedUid == -1)) {
+            return true;
+        }
+
+        List<String> supportedPackages =
+                Arrays.asList(SystemProperties.get("fuse.sys.transcode_package").split(","));
+        for (String callingPackage: callingPackages) {
+            if (supportedPackages.contains(callingPackage)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean supportsTranscode(String path) {
+        File file = new File(path);
+        String name = file.getName();
+        final String cameraRelativePath =
+                String.format("%s/%s/", Environment.DIRECTORY_DCIM, DIRECTORY_CAMERA);
+
+        return !isTranscodeFile(path) && name.endsWith(".mp4") &&
+                cameraRelativePath.equalsIgnoreCase(FileUtils.extractRelativePath(path));
+    }
+
+    private Pair<Long, Integer> getTranscodeCacheInfoFromDB(String path) {
+        try (Cursor cursor = queryFileForTranscode(path, TRANSCODE_CACHE_INFO_PROJECTION)) {
+            if (cursor != null && cursor.moveToNext()) {
+                return Pair.create(cursor.getLong(0), cursor.getInt(1));
+            }
+        }
+        return Pair.create((long)-1, TRANSCODE_EMPTY);
+    }
+
+    public boolean isTranscodeFileCached(String path, String transcodePath) {
+        if (SystemProperties.getBoolean("fuse.sys.disable_transcode_cache", false)) {
+            // Caching is disabled. Hence, delete the cached transcode file.
+            return false;
+        }
+
+        Pair<Long, Integer> cacheInfo = getTranscodeCacheInfoFromDB(path);
+        final long rowId = cacheInfo.first;
+        if (rowId != -1) {
+            final int transcodeStatus = cacheInfo.second;
+            boolean result = transcodePath.equalsIgnoreCase(getTranscodePath(rowId)) &&
+                    transcodeStatus == TRANSCODE_COMPLETE &&
+                    new File(transcodePath).exists();
+            if (result) {
+                logEvent("Transcode cache hit: " + path, true /* toast */, null /* session */);
+            }
+            return result;
+        }
+        return false;
+    }
+
+    private TranscodingSession enqueueTranscodingSession(String src, String dst, int uid,
+            final CountDownLatch latch) throws FileNotFoundException, MediaTranscodingException {
+        int bitRate = 20000000; // 20Mbps
+        int width = 1920;
+        int height = 1080;
+
+        File file = new File(src);
+        File transcodeFile = new File(dst);
+
+        Uri uri = Uri.fromFile(file);
+        Uri transcodeUri = Uri.fromFile(transcodeFile);
+
+        // TODO: Get MediaFormat from database
+        MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC,
+                width, height);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
+
+        TranscodingRequest request =
+                new TranscodingRequest.Builder()
+                        .setClientUid(uid)
+                        .setSourceUri(uri)
+                        .setDestinationUri(transcodeUri)
+                        .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
+                        .setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
+                        .setVideoTrackFormat(format)
+                        .build();
+        TranscodingSession session = mMediaTranscodeManager.enqueueRequest(request,
+                ForegroundThread.getExecutor(),
+                s -> finishTranscodingResult(uid, src, s, latch));
+
+        logEvent("Transcoding start: " + src + ". Uid: " + uid, true /* toast */, session);
+        return session;
+    }
+
+    private boolean waitTranscodingResult(int uid, String src, TranscodingSession session,
+            CountDownLatch latch) {
+        try {
+            int timeout = getTranscodeTimeoutSeconds(src);
+
+            String waitStartLog = "Transcoding wait start: " + src + ". Uid: " + uid + ". Timeout: "
+                    + timeout + "s";
+            logEvent(waitStartLog, false /* toast */, session);
+
+            boolean latchResult = latch.await(timeout, TimeUnit.SECONDS);
+            boolean transcodeResult = session.getResult() == TranscodingSession.RESULT_SUCCESS;
+
+            String waitEndLog = "Transcoding wait end: " + src + ". Uid: " + uid + ". Timeout: "
+                    + !latchResult + ". Success: " + transcodeResult;
+            logEvent(waitEndLog, false /* toast */, session);
+
+            return transcodeResult;
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            Log.w(TAG, "Transcoding latch interrupted." + session);
+            return false;
+        }
+    }
+
+    private int getTranscodeTimeoutSeconds(String file) {
+        double sizeMb = new File(file).length() / (1024 * 1024);
+        return (int) (sizeMb * TRANSCODING_TIMEOUT_COEFFICIENT);
+    }
+
+    private void finishTranscodingResult(int uid, String src, TranscodingSession session,
+            CountDownLatch latch) {
+        synchronized (mTranscodingSessions) {
+            latch.countDown();
+            session.cancel();
+            mTranscodingSessions.remove(src);
+            mTranscodingLatches.remove(session.getSessionId());
+        }
+
+        logEvent("Transcoding end: " + src + ". Uid: " + uid, true /* toast */, session);
+    }
+
+    private boolean updateTranscodeStatus(String path, int transcodeStatus) {
+        final Uri uri = FileUtils.getContentUriForPath(path);
+        // TODO(b/170465810): Replace this with matchUri when the code is refactored.
+        final int match = MediaProvider.FILES;
+        final SQLiteQueryBuilder qb = mMediaProvider.getQueryBuilderForTranscoding(TYPE_UPDATE,
+                match, uri, Bundle.EMPTY, null);
+        final String[] selectionArgs = new String[] {path};
+
+        ContentValues values = new ContentValues();
+        values.put(FileColumns._TRANSCODE_STATUS, transcodeStatus);
+        return qb.update(getDatabaseHelperForUri(uri), values, TRANSCODE_WHERE_CLAUSE,
+                selectionArgs) == 1;
+    }
+
+    public boolean deleteCachedTranscodeFile(long rowId) {
+        return new File(getTranscodeDirectory(), String.valueOf(rowId)).delete();
+    }
+
+    private DatabaseHelper getDatabaseHelperForUri(Uri uri) {
+        final DatabaseHelper helper;
+        try {
+            return mMediaProvider.getDatabaseForUriForTranscoding(uri);
+        } catch (VolumeNotFoundException e) {
+            throw new IllegalStateException("Volume not found while querying transcode path", e);
+        }
+    }
+
+    /**
+     * @return given {@code projection} columns from database for given {@code path}.
+     * Note that cursor might be empty if there is no database row or file is pending or trashed.
+     * TODO(b/170465810): Optimize these queries by bypassing getQueryBuilder(). These queries are
+     * always on Files table and doesn't have any dependency on calling package. i.e., query is
+     * always called with callingPackage=self.
+     */
+    @Nullable
+    private Cursor queryFileForTranscode(String path, String[] projection) {
+        final Uri uri = FileUtils.getContentUriForPath(path);
+        // TODO(b/170465810): Replace this with matchUri when the code is refactored.
+        final int match = MediaProvider.FILES;
+        final SQLiteQueryBuilder qb = mMediaProvider.getQueryBuilderForTranscoding(TYPE_QUERY,
+                match, uri, Bundle.EMPTY, null);
+        final String[] selectionArgs = new String[]{path};
+
+        Bundle extras = new Bundle();
+        extras.putInt(QUERY_ARG_MATCH_PENDING, MATCH_EXCLUDE);
+        extras.putInt(QUERY_ARG_MATCH_TRASHED, MATCH_EXCLUDE);
+        extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, TRANSCODE_WHERE_CLAUSE);
+        extras.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
+        return qb.query(getDatabaseHelperForUri(uri), projection, extras, null);
+    }
+
+    private void logEvent(String event, boolean toast, @Nullable TranscodingSession session) {
+        Log.d(TAG, event + (session == null ? "" : session));
+
+        if (toast && SystemProperties.getBoolean("fuse.sys.transcode_show_toast", false)) {
+            mUiHandler.post(() ->
+                    Toast.makeText(mContext, event, Toast.LENGTH_SHORT).show());
+        }
+    }
+}
diff --git a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
new file mode 100644
index 0000000..66182bc
--- /dev/null
+++ b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.providers.media.photopicker;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+
+import com.android.providers.media.R;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Photo Picker allows users to choose one or more photos and/or videos to share with an app. The
+ * app does not get access to all photos/videos.
+ */
+public class PhotoPickerActivity extends Activity {
+
+    public static final String TAG = "PhotoPickerActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // TODO(b/168001592) Change layout to show photos & options.
+        setContentView(R.layout.photo_picker);
+        Button button = findViewById(R.id.button);
+        button.setOnClickListener(v -> respondEmpty());
+
+        // TODO(b/168001592) Handle multiple selection option.
+
+        // TODO(b/168001592) Filter using given mime type.
+
+        // TODO(b/168001592) Show a photo grid instead of  ListView.
+        ListView photosList = findViewById(R.id.names_list);
+        ArrayAdapter<PhotoEntry> photosAdapter = new ArrayAdapter<>(
+                this, android.R.layout.simple_list_item_1);
+        photosList.setAdapter(photosAdapter);
+        // Clicking an item in the list returns its URI for now.
+        photosList.setOnItemClickListener((parent, view, position, id) -> {
+            respondPhoto(photosAdapter.getItem(position));
+        });
+
+        // Show the list of photo names for now.
+        ImmutableList.Builder<PhotoEntry> imageRowsBuilder = ImmutableList.builder();
+        String[] projection = new String[] {
+                MediaStore.MediaColumns._ID,
+                MediaStore.MediaColumns.DISPLAY_NAME
+        };
+        // TODO(b/168001592) call query() from worker thread.
+        Cursor cursor = getApplicationContext().getContentResolver().query(
+                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+                projection, null, null);
+        int idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID);
+        int nameColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
+        // TODO(b/168001592) Use better image loading (e.g. use paging, glide).
+        while (cursor.moveToNext()) {
+            imageRowsBuilder.add(
+                    new PhotoEntry(cursor.getLong(idColumn), cursor.getString(nameColumn)));
+        }
+        photosAdapter.addAll(imageRowsBuilder.build());
+    }
+
+    private void respondPhoto(PhotoEntry photoEntry) {
+        Uri contentUri = ContentUris.withAppendedId(
+                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+                photoEntry.id);
+
+        Intent response = new Intent();
+        // TODO(b/168001592) Confirm if this flag is enough to grant the access we want.
+        response.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+        // TODO(b/168001592) Use a better label and accurate mime types.
+        if (getIntent().getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)) {
+            ClipDescription clipDescription = new ClipDescription(
+                    "Photo Picker ClipData",
+                    new String[]{"image/*", "video/*"});
+            ClipData clipData = new ClipData(clipDescription, new ClipData.Item(contentUri));
+            response.setClipData(clipData);
+        } else {
+            response.setData(contentUri);
+        }
+
+        setResult(Activity.RESULT_OK, response);
+        finish();
+    }
+
+
+    private void respondEmpty() {
+        setResult(Activity.RESULT_OK);
+        finish();
+    }
+
+    private static class PhotoEntry {
+        private long id;
+        private String name;
+
+        PhotoEntry(long id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+}
diff --git a/src/com/android/providers/media/scan/ModernMediaScanner.java b/src/com/android/providers/media/scan/ModernMediaScanner.java
index adb9941..9e678f1 100644
--- a/src/com/android/providers/media/scan/ModernMediaScanner.java
+++ b/src/com/android/providers/media/scan/ModernMediaScanner.java
@@ -37,6 +37,7 @@
 import static android.media.MediaMetadataRetriever.METADATA_KEY_MIMETYPE;
 import static android.media.MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS;
 import static android.media.MediaMetadataRetriever.METADATA_KEY_TITLE;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_CODEC_MIME_TYPE;
 import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT;
 import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION;
 import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH;
@@ -93,7 +94,6 @@
 import com.android.providers.media.util.ExifUtils;
 import com.android.providers.media.util.FileUtils;
 import com.android.providers.media.util.IsoInterface;
-import com.android.providers.media.util.Logging;
 import com.android.providers.media.util.LongArray;
 import com.android.providers.media.util.Metrics;
 import com.android.providers.media.util.MimeUtils;
@@ -166,10 +166,12 @@
     private static final int MAX_EXCLUDE_DIRS = 450;
 
     private static final Pattern PATTERN_VISIBLE = Pattern.compile(
-            "(?i)^/storage/[^/]+(?:/[0-9]+)?(?:/Android/sandbox/([^/]+))?$");
+            "(?i)^/storage/[^/]+(?:/[0-9]+)?$");
     private static final Pattern PATTERN_INVISIBLE = Pattern.compile(
-            "(?i)^/storage/[^/]+(?:/[0-9]+)?(?:/Android/sandbox/([^/]+))?/" +
-                    "(?:(?:Android/(?:data|obb)$)|(?:(?:Movies|Music|Pictures)/.thumbnails$))");
+            "(?i)^/storage/[^/]+(?:/[0-9]+)?/"
+                    + "(?:(?:Android/(?:data|obb|sandbox)$)|"
+                    + "(?:\\.transcode$)|"
+                    + "(?:(?:Movies|Music|Pictures)/.thumbnails$))");
 
     private static final Pattern PATTERN_YEAR = Pattern.compile("([1-9][0-9][0-9][0-9])");
 
@@ -1201,6 +1203,7 @@
         op.withValue(VideoColumns.COLOR_STANDARD, null);
         op.withValue(VideoColumns.COLOR_TRANSFER, null);
         op.withValue(VideoColumns.COLOR_RANGE, null);
+        op.withValue(FileColumns._VIDEO_CODEC_TYPE, null);
 
         try (FileInputStream is = new FileInputStream(file)) {
             try (MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
@@ -1223,6 +1226,8 @@
                         parseOptional(mmr.extractMetadata(METADATA_KEY_COLOR_TRANSFER)));
                 withOptionalValue(op, VideoColumns.COLOR_RANGE,
                         parseOptional(mmr.extractMetadata(METADATA_KEY_COLOR_RANGE)));
+                withOptionalValue(op, FileColumns._VIDEO_CODEC_TYPE,
+                        parseOptional(mmr.extractMetadata(METADATA_KEY_VIDEO_CODEC_MIME_TYPE)));
             }
 
             // Also hunt around for XMP metadata
diff --git a/src/com/android/providers/media/util/FileUtils.java b/src/com/android/providers/media/util/FileUtils.java
index 3ddec4a..cff4fa7 100644
--- a/src/com/android/providers/media/util/FileUtils.java
+++ b/src/com/android/providers/media/util/FileUtils.java
@@ -856,9 +856,9 @@
     }
 
     public static final Pattern PATTERN_DOWNLOADS_FILE = Pattern.compile(
-            "(?i)^/storage/[^/]+/(?:[0-9]+/)?(?:Android/sandbox/[^/]+/)?Download/.+");
+            "(?i)^/storage/[^/]+/(?:[0-9]+/)?Download/.+");
     public static final Pattern PATTERN_DOWNLOADS_DIRECTORY = Pattern.compile(
-            "(?i)^/storage/[^/]+/(?:[0-9]+/)?(?:Android/sandbox/[^/]+/)?Download/?");
+            "(?i)^/storage/[^/]+/(?:[0-9]+/)?Download/?");
     public static final Pattern PATTERN_EXPIRES_FILE = Pattern.compile(
             "(?i)^\\.(pending|trashed)-(\\d+)-([^/]+)$");
     public static final Pattern PATTERN_PENDING_FILEPATH_FOR_SQL = Pattern.compile(
@@ -899,7 +899,7 @@
      * and which captures the package name as the first group.
      */
     public static final Pattern PATTERN_OWNED_PATH = Pattern.compile(
-            "(?i)^/storage/[^/]+/(?:[0-9]+/)?Android/(?:data|media|obb|sandbox)/([^/]+)(/?.*)?");
+            "(?i)^/storage/[^/]+/(?:[0-9]+/)?Android/(?:data|media|obb)/([^/]+)(/?.*)?");
 
     /**
      * Regex that matches Android/obb or Android/data path.
@@ -923,11 +923,10 @@
     };
 
     /**
-     * Regex that matches paths for {@link MediaColumns#RELATIVE_PATH}; it
-     * captures both top-level paths and sandboxed paths.
+     * Regex that matches paths for {@link MediaColumns#RELATIVE_PATH}
      */
     private static final Pattern PATTERN_RELATIVE_PATH = Pattern.compile(
-            "(?i)^/storage/(?:emulated/[0-9]+/|[^/]+/)(Android/sandbox/([^/]+)/)?");
+            "(?i)^/storage/(?:emulated/[0-9]+/|[^/]+/)");
 
     /**
      * Regex that matches paths under well-known storage paths.
diff --git a/src/com/android/providers/media/util/PermissionUtils.java b/src/com/android/providers/media/util/PermissionUtils.java
index adbe0e2..5021224 100644
--- a/src/com/android/providers/media/util/PermissionUtils.java
+++ b/src/com/android/providers/media/util/PermissionUtils.java
@@ -23,6 +23,7 @@
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OPSTR_LEGACY_STORAGE;
+import static android.app.AppOpsManager.OPSTR_NO_ISOLATED_STORAGE;
 import static android.app.AppOpsManager.OPSTR_READ_MEDIA_AUDIO;
 import static android.app.AppOpsManager.OPSTR_READ_MEDIA_IMAGES;
 import static android.app.AppOpsManager.OPSTR_READ_MEDIA_VIDEO;
@@ -42,8 +43,6 @@
 
 public class PermissionUtils {
 
-    public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
-
     // Callers must hold both the old and new permissions, so that we can
     // handle obscure cases like when an app targets Q but was installed on
     // a device that was originally running on P before being upgraded to Q.
diff --git a/tests/res/raw/large_xmp.mp4 b/tests/res/raw/large_xmp.mp4
new file mode 100644
index 0000000..3dd4b2c
--- /dev/null
+++ b/tests/res/raw/large_xmp.mp4
Binary files differ
diff --git a/tests/src/com/android/providers/media/DatabaseHelperTest.java b/tests/src/com/android/providers/media/DatabaseHelperTest.java
index b2b7825..a9c77b6 100644
--- a/tests/src/com/android/providers/media/DatabaseHelperTest.java
+++ b/tests/src/com/android/providers/media/DatabaseHelperTest.java
@@ -75,7 +75,7 @@
 
     @Test
     public void testFilterVolumeNames() throws Exception {
-        try (DatabaseHelper helper = new DatabaseHelperR(sIsolatedContext, TEST_CLEAN_DB)) {
+        try (DatabaseHelper helper = new DatabaseHelperS(sIsolatedContext, TEST_CLEAN_DB)) {
             SQLiteDatabase db = helper.getWritableDatabaseForTest();
             {
                 final ContentValues values = new ContentValues();
@@ -234,18 +234,23 @@
     }
 
     @Test
-    public void testRtoO() throws Exception {
-        assertDowngrade(DatabaseHelperR.class, DatabaseHelperO.class);
+    public void testStoO() throws Exception {
+        assertDowngrade(DatabaseHelperS.class, DatabaseHelperO.class);
     }
 
     @Test
-    public void testRtoP() throws Exception {
-        assertDowngrade(DatabaseHelperR.class, DatabaseHelperP.class);
+    public void testStoP() throws Exception {
+        assertDowngrade(DatabaseHelperS.class, DatabaseHelperP.class);
     }
 
     @Test
-    public void testRtoQ() throws Exception {
-        assertDowngrade(DatabaseHelperR.class, DatabaseHelperQ.class);
+    public void testStoQ() throws Exception {
+        assertDowngrade(DatabaseHelperS.class, DatabaseHelperQ.class);
+    }
+
+    @Test
+    public void testStoR() throws Exception {
+        assertDowngrade(DatabaseHelperS.class, DatabaseHelperR.class);
     }
 
     private void assertDowngrade(Class<? extends DatabaseHelper> before,
@@ -279,20 +284,25 @@
     }
 
     @Test
-    public void testOtoR() throws Exception {
-        assertRecompute(DatabaseHelperO.class, DatabaseHelperR.class);
-        assertUpgrade(DatabaseHelperO.class, DatabaseHelperR.class);
+    public void testOtoS() throws Exception {
+        assertRecompute(DatabaseHelperO.class, DatabaseHelperS.class);
+        assertUpgrade(DatabaseHelperO.class, DatabaseHelperS.class);
     }
 
     @Test
-    public void testPtoR() throws Exception {
-        assertRecompute(DatabaseHelperP.class, DatabaseHelperR.class);
-        assertUpgrade(DatabaseHelperP.class, DatabaseHelperR.class);
+    public void testPtoS() throws Exception {
+        assertRecompute(DatabaseHelperP.class, DatabaseHelperS.class);
+        assertUpgrade(DatabaseHelperP.class, DatabaseHelperS.class);
     }
 
     @Test
-    public void testQtoR() throws Exception {
-        assertUpgrade(DatabaseHelperQ.class, DatabaseHelperR.class);
+    public void testQtoS() throws Exception {
+        assertUpgrade(DatabaseHelperQ.class, DatabaseHelperS.class);
+    }
+
+    @Test
+    public void testRtoS() throws Exception {
+        assertUpgrade(DatabaseHelperR.class, DatabaseHelperS.class);
     }
 
     private void assertRecompute(Class<? extends DatabaseHelper> before,
@@ -336,17 +346,6 @@
             {
                 final ContentValues values = new ContentValues();
                 values.put(FileColumns.DATA,
-                        "/storage/0000-0000/Android/sandbox/com.example2/Download/dir/foo.mp4");
-                values.put(FileColumns.DATE_ADDED, System.currentTimeMillis());
-                values.put(FileColumns.DATE_MODIFIED, System.currentTimeMillis());
-                values.put(FileColumns.DISPLAY_NAME, "foo.mp4");
-                values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_VIDEO);
-                values.put(FileColumns.MIME_TYPE, "video/mp4");
-                assertFalse(db.insert("files", FileColumns.DATA, values) == -1);
-            }
-            {
-                final ContentValues values = new ContentValues();
-                values.put(FileColumns.DATA,
                         "/storage/emulated/0/Download/foo");
                 values.put(FileColumns.DATE_ADDED, System.currentTimeMillis());
                 values.put(FileColumns.DATE_MODIFIED, System.currentTimeMillis());
@@ -396,18 +395,6 @@
                         c.getString(c.getColumnIndexOrThrow(FileColumns.OWNER_PACKAGE_NAME)));
                 assertEquals("1", c.getString(c.getColumnIndexOrThrow(FileColumns.IS_DOWNLOAD)));
             }
-            try (Cursor c = db.query("files", null, FileColumns.DISPLAY_NAME + "='foo.mp4'",
-                    null, null, null, null)) {
-                assertEquals(1, c.getCount());
-                assertTrue(c.moveToFirst());
-                assertEquals("/storage/0000-0000/Android/sandbox/com.example2/Download/dir/foo.mp4",
-                        c.getString(c.getColumnIndexOrThrow(FileColumns.DATA)));
-                assertEquals("video/mp4",
-                        c.getString(c.getColumnIndexOrThrow(FileColumns.MIME_TYPE)));
-                assertEquals("com.example2",
-                        c.getString(c.getColumnIndexOrThrow(FileColumns.OWNER_PACKAGE_NAME)));
-                assertEquals("1", c.getString(c.getColumnIndexOrThrow(FileColumns.IS_DOWNLOAD)));
-            }
             try (Cursor c = db.query("files", null,
                     FileColumns.DATA + "='/storage/emulated/0/Download/foo'",
                     null, null, null, null)) {
@@ -525,6 +512,19 @@
                     false, false, false, Column.class, null, null,
                     MediaProvider.MIGRATION_LISTENER, null);
         }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            createRSchema(db, false);
+        }
+    }
+
+    private static class DatabaseHelperS extends DatabaseHelper {
+        public DatabaseHelperS(Context context, String name) {
+            super(context, name, DatabaseHelper.VERSION_S,
+                    false, false, false, Column.class, null, null,
+                    MediaProvider.MIGRATION_LISTENER, null);
+        }
     }
 
     /**
@@ -935,4 +935,168 @@
                 + "instance_id,duration,description,orientation,height,is_drm,bucket_display_name,owner_package_name,volume_name,date_modified,date_expires,_display_name,datetaken,mime_type,referer_uri,_id,_data,_hash,_size,title,width,is_trashed,group_id,document_id,is_pending,date_added,download_uri,primary_directory,secondary_directory,original_document_id,bucket_id,relative_path"
                 + " FROM files WHERE is_download=1");
     }
+
+
+    /**
+     * Snapshot of {@link DatabaseHelper#createLatestSchema} as of
+     * {@link android.os.Build.VERSION_CODES#R}.
+     */
+    private static void createRSchema(SQLiteDatabase db, boolean internal) {
+        makePristineSchema(db);
+
+        // CAUTION: THIS IS A SNAPSHOTTED GOLDEN SCHEMA THAT SHOULD NEVER BE
+        // DIRECTLY MODIFIED, SINCE IT REPRESENTS A DEVICE IN THE WILD THAT WE
+        // MUST SUPPORT. IF TESTS ARE FAILING, THE CORRECT FIX IS TO ADJUST THE
+        // DATABASE UPGRADE LOGIC TO MIGRATE THIS SNAPSHOTTED GOLDEN SCHEMA TO
+        // THE LATEST SCHEMA.
+
+        db.execSQL("CREATE TABLE local_metadata (generation INTEGER DEFAULT 0)");
+        db.execSQL("INSERT INTO local_metadata VALUES (0)");
+
+        db.execSQL("CREATE TABLE android_metadata (locale TEXT)");
+        db.execSQL("CREATE TABLE thumbnails (_id INTEGER PRIMARY KEY,_data TEXT,image_id INTEGER,"
+                + "kind INTEGER,width INTEGER,height INTEGER)");
+        db.execSQL("CREATE TABLE album_art (album_id INTEGER PRIMARY KEY,_data TEXT)");
+        db.execSQL("CREATE TABLE videothumbnails (_id INTEGER PRIMARY KEY,_data TEXT,"
+                + "video_id INTEGER,kind INTEGER,width INTEGER,height INTEGER)");
+        db.execSQL("CREATE TABLE files (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+                + "_data TEXT UNIQUE COLLATE NOCASE,_size INTEGER,format INTEGER,parent INTEGER,"
+                + "date_added INTEGER,date_modified INTEGER,mime_type TEXT,title TEXT,"
+                + "description TEXT,_display_name TEXT,picasa_id TEXT,orientation INTEGER,"
+                + "latitude DOUBLE,longitude DOUBLE,datetaken INTEGER,mini_thumb_magic INTEGER,"
+                + "bucket_id TEXT,bucket_display_name TEXT,isprivate INTEGER,title_key TEXT,"
+                + "artist_id INTEGER,album_id INTEGER,composer TEXT,track INTEGER,"
+                + "year INTEGER CHECK(year!=0),is_ringtone INTEGER,is_music INTEGER,"
+                + "is_alarm INTEGER,is_notification INTEGER,is_podcast INTEGER,album_artist TEXT,"
+                + "duration INTEGER,bookmark INTEGER,artist TEXT,album TEXT,resolution TEXT,"
+                + "tags TEXT,category TEXT,language TEXT,mini_thumb_data TEXT,name TEXT,"
+                + "media_type INTEGER,old_id INTEGER,is_drm INTEGER,"
+                + "width INTEGER, height INTEGER, title_resource_uri TEXT,"
+                + "owner_package_name TEXT DEFAULT NULL,"
+                + "color_standard INTEGER, color_transfer INTEGER, color_range INTEGER,"
+                + "_hash BLOB DEFAULT NULL, is_pending INTEGER DEFAULT 0,"
+                + "is_download INTEGER DEFAULT 0, download_uri TEXT DEFAULT NULL,"
+                + "referer_uri TEXT DEFAULT NULL, is_audiobook INTEGER DEFAULT 0,"
+                + "date_expires INTEGER DEFAULT NULL,is_trashed INTEGER DEFAULT 0,"
+                + "group_id INTEGER DEFAULT NULL,primary_directory TEXT DEFAULT NULL,"
+                + "secondary_directory TEXT DEFAULT NULL,document_id TEXT DEFAULT NULL,"
+                + "instance_id TEXT DEFAULT NULL,original_document_id TEXT DEFAULT NULL,"
+                + "relative_path TEXT DEFAULT NULL,volume_name TEXT DEFAULT NULL,"
+                + "artist_key TEXT DEFAULT NULL,album_key TEXT DEFAULT NULL,"
+                + "genre TEXT DEFAULT NULL,genre_key TEXT DEFAULT NULL,genre_id INTEGER,"
+                + "author TEXT DEFAULT NULL, bitrate INTEGER DEFAULT NULL,"
+                + "capture_framerate REAL DEFAULT NULL, cd_track_number TEXT DEFAULT NULL,"
+                + "compilation INTEGER DEFAULT NULL, disc_number TEXT DEFAULT NULL,"
+                + "is_favorite INTEGER DEFAULT 0, num_tracks INTEGER DEFAULT NULL,"
+                + "writer TEXT DEFAULT NULL, exposure_time TEXT DEFAULT NULL,"
+                + "f_number TEXT DEFAULT NULL, iso INTEGER DEFAULT NULL,"
+                + "scene_capture_type INTEGER DEFAULT NULL, generation_added INTEGER DEFAULT 0,"
+                + "generation_modified INTEGER DEFAULT 0, xmp BLOB DEFAULT NULL)");
+
+        db.execSQL("CREATE TABLE log (time DATETIME, message TEXT)");
+        if (!internal) {
+            db.execSQL("CREATE TABLE audio_playlists_map (_id INTEGER PRIMARY KEY,"
+                    + "audio_id INTEGER NOT NULL,playlist_id INTEGER NOT NULL,"
+                    + "play_order INTEGER NOT NULL)");
+        }
+
+        db.execSQL("CREATE VIEW searchhelpertitle AS SELECT * FROM audio ORDER BY title_key");
+        db.execSQL("CREATE VIEW search AS SELECT _id,'artist' AS mime_type,artist,NULL AS album,"
+                + "NULL AS title,artist AS text1,NULL AS text2,number_of_albums AS data1,"
+                + "number_of_tracks AS data2,artist_key AS match,"
+                + "'content://media/external/audio/artists/'||_id AS suggest_intent_data,"
+                + "1 AS grouporder FROM artist_info WHERE (artist!='<unknown>')"
+                + " UNION ALL SELECT _id,'album' AS mime_type,artist,album,"
+                + "NULL AS title,album AS text1,artist AS text2,NULL AS data1,"
+                + "NULL AS data2,artist_key||' '||album_key AS match,"
+                + "'content://media/external/audio/albums/'||_id AS suggest_intent_data,"
+                + "2 AS grouporder FROM album_info"
+                + " WHERE (album!='<unknown>')"
+                + " UNION ALL SELECT searchhelpertitle._id AS _id,mime_type,artist,album,title,"
+                + "title AS text1,artist AS text2,NULL AS data1,"
+                + "NULL AS data2,artist_key||' '||album_key||' '||title_key AS match,"
+                + "'content://media/external/audio/media/'||searchhelpertitle._id"
+                + " AS suggest_intent_data,"
+                + "3 AS grouporder FROM searchhelpertitle WHERE (title != '')");
+
+        db.execSQL("CREATE VIEW audio AS SELECT "
+                + "title_key,instance_id,compilation,disc_number,duration,is_ringtone,album_artist,resolution,orientation,artist,author,height,is_drm,bucket_display_name,is_audiobook,owner_package_name,volume_name,title_resource_uri,date_modified,writer,date_expires,composer,_display_name,datetaken,mime_type,is_notification,bitrate,cd_track_number,_id,xmp,year,_data,_size,album,genre,is_alarm,title,track,width,is_music,album_key,is_favorite,is_trashed,group_id,document_id,artist_id,generation_added,artist_key,genre_key,is_download,generation_modified,is_pending,date_added,is_podcast,capture_framerate,album_id,num_tracks,original_document_id,genre_id,bucket_id,bookmark,relative_path"
+                + " FROM files WHERE media_type=2");
+        db.execSQL("CREATE VIEW video AS SELECT"
+                +  " instance_id,compilation,disc_number,duration,album_artist,description,language,resolution,latitude,orientation,artist,color_transfer,author,color_standard,height,is_drm,bucket_display_name,owner_package_name,volume_name,date_modified,writer,date_expires,composer,_display_name,datetaken,mime_type,bitrate,cd_track_number,_id,xmp,tags,year,category,_data,_size,album,genre,title,width,longitude,is_favorite,is_trashed,group_id,document_id,generation_added,is_download,generation_modified,is_pending,date_added,mini_thumb_magic,capture_framerate,color_range,num_tracks,isprivate,original_document_id,bucket_id,bookmark,relative_path"
+                + " FROM files WHERE media_type=3");
+        db.execSQL("CREATE VIEW images AS SELECT"
+                + " instance_id,compilation,disc_number,duration,album_artist,description,picasa_id,resolution,latitude,orientation,artist,author,height,is_drm,bucket_display_name,owner_package_name,f_number,volume_name,date_modified,writer,date_expires,composer,_display_name,scene_capture_type,datetaken,mime_type,bitrate,cd_track_number,_id,iso,xmp,year,_data,_size,album,genre,title,width,longitude,is_favorite,is_trashed,exposure_time,group_id,document_id,generation_added,is_download,generation_modified,is_pending,date_added,mini_thumb_magic,capture_framerate,num_tracks,isprivate,original_document_id,bucket_id,relative_path"
+                + " FROM files WHERE media_type=1");
+        db.execSQL("CREATE VIEW downloads AS SELECT"
+                + " instance_id,compilation,disc_number,duration,album_artist,description,resolution,orientation,artist,author,height,is_drm,bucket_display_name,owner_package_name,volume_name,date_modified,writer,date_expires,composer,_display_name,datetaken,mime_type,bitrate,cd_track_number,referer_uri,_id,xmp,year,_data,_size,album,genre,title,width,is_favorite,is_trashed,group_id,document_id,generation_added,is_download,generation_modified,is_pending,date_added,download_uri,capture_framerate,num_tracks,original_document_id,bucket_id,relative_path"
+                + " FROM files WHERE is_download=1");
+
+        db.execSQL("CREATE VIEW audio_artists AS SELECT "
+                + "  artist_id AS " + "_id"
+                + ", MIN(artist) AS " + "artist"
+                + ", artist_key AS " + "artist_key"
+                + ", COUNT(DISTINCT album_id) AS " + "number_of_albums"
+                + ", COUNT(DISTINCT _id) AS " + "number_of_tracks"
+                + " FROM audio"
+                + " WHERE is_music=1"
+                + " GROUP BY artist_id");
+
+        db.execSQL("CREATE VIEW audio_albums AS SELECT "
+                + "  album_id AS " + "_id"
+                + ", album_id AS " + "album_id"
+                + ", MIN(album) AS " + "album"
+                + ", album_key AS " + "album_key"
+                + ", artist_id AS " + "artist_id"
+                + ", artist AS " + "artist"
+                + ", artist_key AS " + "artist_key"
+                + ", COUNT(DISTINCT _id) AS " + "numsongs"
+                + ", COUNT(DISTINCT _id) AS " + "numsongs_by_artist"
+                + ", MIN(year) AS " + "minyear"
+                + ", MAX(year) AS " + "maxyear"
+                + ", NULL AS " + "album_art"
+                + " FROM audio"
+                + " WHERE is_music=1"
+                + " GROUP BY album_id");
+
+        db.execSQL("CREATE VIEW audio_genres AS SELECT "
+                + "  genre_id AS " + "_id"
+                + ", MIN(genre) AS " + "name"
+                + " FROM audio"
+                + " GROUP BY genre_id");
+
+        final String insertArg =
+                "new.volume_name||':'||new._id||':'||new.media_type||':'||new.is_download";
+        final String updateArg =
+                "old.volume_name||':'||old._id||':'||old.media_type||':'||old.is_download"
+                        + "||':'||new._id||':'||new.media_type||':'||new.is_download"
+                        + "||':'||ifnull(old.owner_package_name,'null')"
+                        + "||':'||ifnull(new.owner_package_name,'null')||':'||old._data";
+        final String deleteArg =
+                "old.volume_name||':'||old._id||':'||old.media_type||':'||old.is_download"
+                        + "||':'||ifnull(old.owner_package_name,'null')||':'||old._data";
+
+        db.execSQL("CREATE TRIGGER files_insert AFTER INSERT ON files"
+                + " BEGIN SELECT _INSERT(" + insertArg + "); END");
+        db.execSQL("CREATE TRIGGER files_update AFTER UPDATE ON files"
+                + " BEGIN SELECT _UPDATE(" + updateArg + "); END");
+        db.execSQL("CREATE TRIGGER files_delete AFTER DELETE ON files"
+                + " BEGIN SELECT _DELETE(" + deleteArg + "); END");
+
+        db.execSQL("CREATE INDEX image_id_index on thumbnails(image_id)");
+        db.execSQL("CREATE INDEX video_id_index on videothumbnails(video_id)");
+        db.execSQL("CREATE INDEX album_id_idx ON files(album_id)");
+        db.execSQL("CREATE INDEX artist_id_idx ON files(artist_id)");
+        db.execSQL("CREATE INDEX genre_id_idx ON files(genre_id)");
+        db.execSQL("CREATE INDEX bucket_index on files(bucket_id,media_type,datetaken, _id)");
+        db.execSQL("CREATE INDEX bucket_name on files(bucket_id,media_type,bucket_display_name)");
+        db.execSQL("CREATE INDEX format_index ON files(format)");
+        db.execSQL("CREATE INDEX media_type_index ON files(media_type)");
+        db.execSQL("CREATE INDEX parent_index ON files(parent)");
+        db.execSQL("CREATE INDEX path_index ON files(_data)");
+        db.execSQL("CREATE INDEX sort_index ON files(datetaken ASC, _id ASC)");
+        db.execSQL("CREATE INDEX title_idx ON files(title)");
+        db.execSQL("CREATE INDEX titlekey_index ON files(title_key)");
+    }
+
 }
diff --git a/tests/src/com/android/providers/media/MediaProviderTest.java b/tests/src/com/android/providers/media/MediaProviderTest.java
index 76faa16..30df5dc 100644
--- a/tests/src/com/android/providers/media/MediaProviderTest.java
+++ b/tests/src/com/android/providers/media/MediaProviderTest.java
@@ -434,8 +434,6 @@
                 getPathOwnerPackageName("/storage/emulated/0/Android/obb/com.example/foo.jpg"));
         assertEquals("com.example",
                 getPathOwnerPackageName("/storage/emulated/0/Android/media/com.example/foo.jpg"));
-        assertEquals("com.example",
-                getPathOwnerPackageName("/storage/emulated/0/Android/sandbox/com.example/foo.jpg"));
     }
 
     @Test
@@ -832,36 +830,19 @@
         assertTrue(isDownload("/storage/emulated/0/Download/test.pdf"));
         assertTrue(isDownload("/storage/emulated/0/Download/dir/foo.mp4"));
         assertTrue(isDownload("/storage/0000-0000/Download/foo.txt"));
-        assertTrue(isDownload(
-                "/storage/emulated/0/Android/sandbox/com.example/Download/colors.png"));
-        assertTrue(isDownload(
-                "/storage/emulated/0/Android/sandbox/shared-com.uid.shared/Download/colors.png"));
-        assertTrue(isDownload(
-                "/storage/0000-0000/Android/sandbox/com.example/Download/colors.png"));
-        assertTrue(isDownload(
-                "/storage/0000-0000/Android/sandbox/shared-com.uid.shared/Download/colors.png"));
-
 
         assertFalse(isDownload("/storage/emulated/0/Pictures/colors.png"));
         assertFalse(isDownload("/storage/emulated/0/Pictures/Download/colors.png"));
         assertFalse(isDownload("/storage/emulated/0/Android/data/com.example/Download/foo.txt"));
-        assertFalse(isDownload(
-                "/storage/emulated/0/Android/sandbox/com.example/dir/Download/foo.txt"));
         assertFalse(isDownload("/storage/emulated/0/Download"));
-        assertFalse(isDownload("/storage/emulated/0/Android/sandbox/com.example/Download"));
-        assertFalse(isDownload(
-                "/storage/0000-0000/Android/sandbox/shared-com.uid.shared/Download"));
     }
 
     @Test
     public void testIsDownloadDir() throws Exception {
         assertTrue(isDownloadDir("/storage/emulated/0/Download"));
-        assertTrue(isDownloadDir("/storage/emulated/0/Android/sandbox/com.example/Download"));
 
         assertFalse(isDownloadDir("/storage/emulated/0/Download/colors.png"));
         assertFalse(isDownloadDir("/storage/emulated/0/Download/dir/"));
-        assertFalse(isDownloadDir(
-                "/storage/emulated/0/Android/sandbox/com.example/Download/dir/foo.txt"));
     }
 
     @Test
@@ -922,7 +903,6 @@
 
         for (String top : new String[] {
                 "/storage/emulated/0",
-                "/storage/emulated/0/Android/sandbox/com.example",
         }) {
             values = computeDataValues(top + "/IMG1024.JPG");
             assertVolume(values, MediaStore.VOLUME_EXTERNAL_PRIMARY);
diff --git a/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java b/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
index 1c86ed8..9b7f0d2 100644
--- a/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
+++ b/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
@@ -383,15 +383,11 @@
     public void testShouldScanPathAndIsPathHidden() {
         for (String prefix : new String[] {
                 "/storage/emulated/0",
-                "/storage/emulated/0/Android/sandbox/com.example",
                 "/storage/0000-0000",
-                "/storage/0000-0000/Android/sandbox/com.example",
         }) {
             assertShouldScanPathAndIsPathHidden(true, false, new File(prefix));
             assertShouldScanPathAndIsPathHidden(true, false, new File(prefix + "/meow"));
             assertShouldScanPathAndIsPathHidden(true, false, new File(prefix + "/Android/meow"));
-            assertShouldScanPathAndIsPathHidden(true, false,
-                    new File(prefix + "/Android/sandbox/meow"));
 
             assertShouldScanPathAndIsPathHidden(true, true, new File(prefix + "/.meow/dir"));
 
@@ -407,6 +403,9 @@
                     new File(prefix + "/Movies/.thumbnails/meow"));
             assertShouldScanPathAndIsPathHidden(false, false,
                     new File(prefix + "/Music/.thumbnails/meow"));
+
+            assertShouldScanPathAndIsPathHidden(false, false,
+                    new File(prefix + "/.transcode/meow"));
         }
     }
 
@@ -457,26 +456,24 @@
     public void testShouldScanDirectory() throws Exception {
         for (String prefix : new String[] {
                 "/storage/emulated/0",
-                "/storage/emulated/0/Android/sandbox/com.example",
                 "/storage/0000-0000",
-                "/storage/0000-0000/Android/sandbox/com.example",
         }) {
             assertShouldScanDirectory(new File(prefix));
             assertShouldScanDirectory(new File(prefix + "/meow"));
             assertShouldScanDirectory(new File(prefix + "/Android"));
             assertShouldScanDirectory(new File(prefix + "/Android/meow"));
-            assertShouldScanDirectory(new File(prefix + "/Android/sandbox"));
-            assertShouldScanDirectory(new File(prefix + "/Android/sandbox/meow"));
             assertShouldScanDirectory(new File(prefix + "/.meow"));
 
             assertShouldntScanDirectory(new File(prefix + "/Android/data"));
             assertShouldntScanDirectory(new File(prefix + "/Android/obb"));
+            assertShouldntScanDirectory(new File(prefix + "/Android/sandbox"));
 
             assertShouldntScanDirectory(new File(prefix + "/Pictures/.thumbnails"));
             assertShouldntScanDirectory(new File(prefix + "/Movies/.thumbnails"));
             assertShouldntScanDirectory(new File(prefix + "/Music/.thumbnails"));
 
             assertShouldScanDirectory(new File(prefix + "/DCIM/.thumbnails"));
+            assertShouldntScanDirectory(new File(prefix + "/.transcode"));
         }
     }
 
@@ -492,9 +489,7 @@
     public void testIsDirectoryHidden() throws Exception {
         for (String prefix : new String[] {
                 "/storage/emulated/0",
-                "/storage/emulated/0/Android/sandbox/com.example",
                 "/storage/0000-0000",
-                "/storage/0000-0000/Android/sandbox/com.example",
         }) {
             assertDirectoryNotHidden(new File(prefix));
             assertDirectoryNotHidden(new File(prefix + "/meow"));
@@ -1035,4 +1030,21 @@
             assertEquals(0, cursor.getCount());
         }
     }
+
+    @Test
+    public void testScan_largeXmpData() throws Exception {
+        final File image = new File(mDir, "large_xmp.mp4");
+        stage(R.raw.large_xmp, image);
+        assertTrue(image.exists());
+
+        mModern.scanDirectory(mDir, REASON_UNKNOWN);
+
+        try (Cursor cursor = mIsolatedResolver
+                .query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+                 new String[] { MediaColumns.XMP }, null, null, null)) {
+             assertEquals(1, cursor.getCount());
+             cursor.moveToFirst();
+             assertEquals(0, cursor.getBlob(0).length);
+        }
+    }
 }
diff --git a/tests/transcode/Android.bp b/tests/transcode/Android.bp
new file mode 100644
index 0000000..7326386
--- /dev/null
+++ b/tests/transcode/Android.bp
@@ -0,0 +1,30 @@
+android_test {
+    name: "MediaProviderTranscodeTests",
+    test_suites: [
+        "device-tests",
+        "mts",
+    ],
+    compile_multilib: "both",
+
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        "src/**/*.java",
+    ],
+
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+    ],
+
+    static_libs: [
+        "androidx.test.rules",
+        "cts-install-lib",
+        "collector-device-lib-platform",
+        "mockito-target",
+        "truth-prebuilt",
+    ],
+
+    certificate: "media",
+}
diff --git a/tests/transcode/AndroidManifest.xml b/tests/transcode/AndroidManifest.xml
new file mode 100644
index 0000000..99254f4
--- /dev/null
+++ b/tests/transcode/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.providers.media.transcode"
+    android:sharedUserId="android.media">
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application android:label="MediaProvider Transcode Tests">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.providers.media.transcode"
+        android:label="MediaProvider Transcode Tests" />
+
+</manifest>
diff --git a/tests/transcode/AndroidTest.xml b/tests/transcode/AndroidTest.xml
new file mode 100644
index 0000000..97fce01
--- /dev/null
+++ b/tests/transcode/AndroidTest.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.
+-->
+<configuration description="Runs Tests for MediaProvder.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="MediaProviderTranscodeTests.apk" />
+        <option name="install-arg" value="-g" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="MediaProviderTranscodeTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.providers.media.transcode" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/tests/transcode/res/raw/testvideo_HEVC.mp4 b/tests/transcode/res/raw/testvideo_HEVC.mp4
new file mode 100644
index 0000000..8a3dba2
--- /dev/null
+++ b/tests/transcode/res/raw/testvideo_HEVC.mp4
Binary files differ
diff --git a/tests/transcode/src/com/android/providers/media/transcode/TranscodeTest.java b/tests/transcode/src/com/android/providers/media/transcode/TranscodeTest.java
new file mode 100644
index 0000000..8c363be
--- /dev/null
+++ b/tests/transcode/src/com/android/providers/media/transcode/TranscodeTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.providers.media.transcode;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Environment;
+import android.system.Os;
+
+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.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class TranscodeTest {
+    private static final File EXTERNAL_STORAGE_DIRECTORY
+            = Environment.getExternalStorageDirectory();
+    private static final File DIR_CAMERA
+            = new File(EXTERNAL_STORAGE_DIRECTORY, Environment.DIRECTORY_DCIM + "/Camera");
+
+    static final String NONCE = String.valueOf(System.nanoTime());
+    private static final String HEVC_FILE_NAME = "TranscodeTestHEVC_" + NONCE + ".mp4";
+
+    @Before
+    public void setUp() throws Exception {
+        TranscodeTestUtils.pollForExternalStorageState();
+        TranscodeTestUtils.enableSeamlessTranscoding();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        TranscodeTestUtils.disableSeamlessTranscoding();
+    }
+
+    /**
+     * Tests that we return FD of transcoded file for legacy apps
+     * @throws Exception
+     */
+    @Test
+    public void testTranscoded() throws Exception {
+        File modernFile = new File(DIR_CAMERA, HEVC_FILE_NAME);
+        try {
+            TranscodeTestUtils.stageHEVCVideoFile(modernFile);
+            long size = modernFile.length();
+
+            FileInputStream fisOriginal = new FileInputStream(modernFile);
+
+            TranscodeTestUtils.setLegacy(Os.getuid());
+
+            FileInputStream fisTranscoded = new FileInputStream(modernFile);
+
+            assertFileContent(fisOriginal, fisTranscoded, size, false);
+
+            fisOriginal.close();
+            fisTranscoded.close();
+        } finally {
+            TranscodeTestUtils.unsetLegacy();
+            modernFile.delete();
+        }
+    }
+
+    /**
+     * Tests that same transcoded file is used for multiple open() from same app
+     * @throws Exception
+     */
+    @Test
+    public void testSameTranscodedFile() throws Exception {
+        File modernFile = new File(DIR_CAMERA, HEVC_FILE_NAME);
+        try {
+            TranscodeTestUtils.stageHEVCVideoFile(modernFile);
+            long size = modernFile.length();
+
+            TranscodeTestUtils.setLegacy(Os.getuid());
+
+            FileInputStream fisTranscoded1 = new FileInputStream(modernFile);
+            FileInputStream fisTranscoded2 = new FileInputStream(modernFile);
+
+            assertFileContent(fisTranscoded1, fisTranscoded2, size, true);
+
+            fisTranscoded1.close();
+            fisTranscoded2.close();
+        } finally {
+            TranscodeTestUtils.unsetLegacy();
+            modernFile.delete();
+        }
+    }
+
+    private void assertFileContent(FileInputStream fisOriginal, FileInputStream fisTranscoded,
+            long fileSize, boolean assertSame) throws IOException {
+        final int readBytesLen = 10;
+        byte[] original = new byte[readBytesLen];
+        byte[] transcoded = new byte[readBytesLen];
+        long ind = 0;
+        final int seekLen = 1024;
+        boolean isSame = true;
+
+        while (isSame && ind < fileSize) {
+            assertEquals(readBytesLen, fisOriginal.read(original));
+            assertEquals(readBytesLen, fisTranscoded.read(transcoded));
+
+            isSame = Arrays.equals(original, transcoded);
+
+            ind += seekLen;
+            fisOriginal.skip(seekLen);
+            fisTranscoded.skip(seekLen);
+        }
+        assertEquals(assertSame, isSame);
+    }
+}
diff --git a/tests/transcode/src/com/android/providers/media/transcode/TranscodeTestUtils.java b/tests/transcode/src/com/android/providers/media/transcode/TranscodeTestUtils.java
new file mode 100644
index 0000000..9a8b881
--- /dev/null
+++ b/tests/transcode/src/com/android/providers/media/transcode/TranscodeTestUtils.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.providers.media.transcode;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static org.junit.Assert.assertTrue;
+
+import android.app.UiAutomation;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.provider.MediaStore;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.google.common.io.ByteStreams;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Supplier;
+
+public class TranscodeTestUtils {
+    private static final String TAG = "TranscodeTestUtils";
+
+    private static final long POLLING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20);
+    private static final long POLLING_SLEEP_MILLIS = 100;
+
+    public static void stageHEVCVideoFile(File videoFile) throws IOException {
+        if (!videoFile.getParentFile().exists()) {
+            assertTrue(videoFile.getParentFile().mkdirs());
+        }
+        try (InputStream in =
+                     getContext().getResources().openRawResource(R.raw.testvideo_HEVC);
+             FileOutputStream out = new FileOutputStream(videoFile)) {
+            FileUtils.copy(in, out);
+            // Sync file to disk to ensure file is fully written to the lower fs before scanning
+            // Otherwise, media provider might try to read the file on the lower fs and not see
+            // the fully written bytes
+            out.getFD().sync();
+        }
+        // MediaProvider treats this app as app with MANAGE_EXTERNAL_STORAGE,
+        // so we have to explicitly insert this file to database.
+        MediaStore.scanFile(getContext().getContentResolver(), videoFile);
+    }
+
+    public static void enableSeamlessTranscoding() throws Exception {
+        executeShellCommand("setprop persist.fuse.sys.transcode true");
+    }
+
+    public static void disableSeamlessTranscoding() throws Exception {
+        executeShellCommand("setprop persist.fuse.sys.transcode false");
+    }
+
+    public static void setLegacy(int uid) throws IOException {
+        final String command = "setprop fuse.sys.transcode_uid " +  uid;
+        executeShellCommand(command);
+    }
+
+    public static void setLegacyAll() throws IOException {
+        final String command = "setprop fuse.sys.transcode_uid " + -1;
+        executeShellCommand(command);
+    }
+
+    public static void unsetLegacy() throws IOException {
+        final String command = "setprop fuse.sys.transcode_uid " + -2;
+        executeShellCommand(command);
+    }
+
+    /**
+     * Executes a shell command.
+     */
+    public static String executeShellCommand(String command) throws IOException {
+        int attempt = 0;
+        while (attempt++ < 5) {
+            try {
+                return executeShellCommandInternal(command);
+            } catch (InterruptedIOException e) {
+                // Hmm, we had trouble executing the shell command; the best we
+                // can do is try again a few more times
+                Log.v(TAG, "Trouble executing " + command + "; trying again", e);
+            }
+        }
+        throw new IOException("Failed to execute " + command);
+    }
+
+    private static String executeShellCommandInternal(String cmd) throws IOException {
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try (FileInputStream output = new FileInputStream(
+                uiAutomation.executeShellCommand(cmd).getFileDescriptor())) {
+            return new String(ByteStreams.toByteArray(output));
+        }
+    }
+
+    /**
+     * Polls for external storage to be mounted.
+     */
+    public static void pollForExternalStorageState() throws Exception {
+        pollForCondition(
+                () -> Environment.getExternalStorageState(Environment.getExternalStorageDirectory())
+                        .equals(Environment.MEDIA_MOUNTED),
+                "Timed out while waiting for ExternalStorageState to be MEDIA_MOUNTED");
+    }
+
+    private static void pollForCondition(Supplier<Boolean> condition, String errorMessage)
+            throws Exception {
+        for (int i = 0; i < POLLING_TIMEOUT_MILLIS / POLLING_SLEEP_MILLIS; i++) {
+            if (condition.get()) {
+                return;
+            }
+            Thread.sleep(POLLING_SLEEP_MILLIS);
+        }
+        throw new TimeoutException(errorMessage);
+    }
+
+}
diff --git a/tools/dialogs/AndroidManifest.xml b/tools/dialogs/AndroidManifest.xml
index 947f1bd..8ee5f2c 100644
--- a/tools/dialogs/AndroidManifest.xml
+++ b/tools/dialogs/AndroidManifest.xml
@@ -1,14 +1,17 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.providers.media.tools.dialogs">
+<?xml version="1.0" encoding="utf-8"?>
 
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+     package="com.android.providers.media.tools.dialogs">
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
     <application android:label="DialogsTool">
-        <activity android:name=".DialogsActivity">
+        <activity android:name=".DialogsActivity"
+             android:exported="true">
             <intent-filter android:label="DialogsTool">
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
          </activity>
     </application>